From 2f30950143cc70bc42a3c8a4111d7cf8198ec881 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 May 2009 10:38:43 -0700 Subject: ruby: Import ruby and slicc from GEMS We eventually plan to replace the m5 cache hierarchy with the GEMS hierarchy, but for now we will make both live alongside eachother. --- src/mem/slicc/parser/lexer.ll | 118 ++++++++++++++ src/mem/slicc/parser/parser.yy | 352 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 470 insertions(+) create mode 100644 src/mem/slicc/parser/lexer.ll create mode 100644 src/mem/slicc/parser/parser.yy (limited to 'src/mem/slicc/parser') diff --git a/src/mem/slicc/parser/lexer.ll b/src/mem/slicc/parser/lexer.ll new file mode 100644 index 000000000..7903b0ee7 --- /dev/null +++ b/src/mem/slicc/parser/lexer.ll @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +%{ + +#include +#include "ASTs.hh" +#include "parser.h" +#include + +extern "C" int yylex(); +extern "C" void yyerror(); +extern "C" int yywrap() +{ + return 1; +} + +%} +%x CMNT +%x IMBEDED +%% + +[\t ]+ /* Ignore whitespace */ +[\n] { g_line_number++; } +"//".*[\n] { g_line_number++; } /* C++ style comments */ + +"/*" BEGIN CMNT; +. ; +\n { g_line_number++; } +"*/" { BEGIN INITIAL; } + +true { yylval.str_ptr = new string(yytext); return LIT_BOOL; } +false { yylval.str_ptr = new string(yytext); return LIT_BOOL; } +global { return GLOBAL_DECL; } +machine { return MACHINE_DECL; } +in_port { return IN_PORT_DECL; } +out_port { return OUT_PORT_DECL; } +action { return ACTION_DECL; } +transition { return TRANSITION_DECL; } +structure { return STRUCT_DECL; } +external_type { return EXTERN_TYPE_DECL; } +enumeration { return ENUM_DECL; } +peek { return PEEK; } +enqueue { return ENQUEUE; } +copy_head { return COPY_HEAD; } +check_allocate { return CHECK_ALLOCATE; } +check_stop_slots { return CHECK_STOP_SLOTS; } +if { return IF; } +else { return ELSE; } +return { return RETURN; } +THIS { return THIS; } +CHIP { return CHIP; } +void { yylval.str_ptr = new string(yytext); return VOID; } + +== { yylval.str_ptr = new string(yytext); return EQ; } +!= { yylval.str_ptr = new string(yytext); return NE; } +[<] { yylval.str_ptr = new string(yytext); return '<'; } +[>] { yylval.str_ptr = new string(yytext); return '>'; } +[<][<] { yylval.str_ptr = new string(yytext); return LEFTSHIFT; } +[>][>] { yylval.str_ptr = new string(yytext); return RIGHTSHIFT; } +[<][=] { yylval.str_ptr = new string(yytext); return LE; } +[>][=] { yylval.str_ptr = new string(yytext); return GE; } +[!] { yylval.str_ptr = new string(yytext); return NOT; } +[&][&] { yylval.str_ptr = new string(yytext); return AND; } +[|][|] { yylval.str_ptr = new string(yytext); return OR; } +[+] { yylval.str_ptr = new string(yytext); return PLUS; } +[-] { yylval.str_ptr = new string(yytext); return DASH; } +[*] { yylval.str_ptr = new string(yytext); return STAR; } +[/] { yylval.str_ptr = new string(yytext); return SLASH; } +:: { return DOUBLE_COLON; } +[:] { return ':'; } +[;] { return SEMICOLON; } +[[] { return '['; } +[]] { return ']'; } +[{] { return '{'; } +[}] { return '}'; } +[(] { return '('; } +[)] { return ')'; } +[,] { return ','; } +[=] { return '='; } +:= { return ASSIGN; } +[.] { return DOT; } + +[0-9]*[.][0-9]* { yylval.str_ptr = new string(yytext); return FLOATNUMBER; } +[0-9]* { yylval.str_ptr = new string(yytext); return NUMBER; } +[a-zA-Z_][a-zA-Z_0-9]{0,50} { yylval.str_ptr = new string(yytext); return IDENT; } +\"[^"\n]*\" { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } +\'[^'\n]*\' { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } + +. { return OTHER; } /* Need so that we handle all characters */ + +%% + diff --git a/src/mem/slicc/parser/parser.yy b/src/mem/slicc/parser/parser.yy new file mode 100644 index 000000000..f4d9a1a62 --- /dev/null +++ b/src/mem/slicc/parser/parser.yy @@ -0,0 +1,352 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +%{ +#include +#include +#include +#include "ASTs.hh" + +#define YYMAXDEPTH 100000 +#define YYERROR_VERBOSE + +extern char* yytext; + +extern "C" void yyerror(char*); +extern "C" int yylex(); + +%} + +%union { + string* str_ptr; + Vector* string_vector_ptr; + + // Decls + DeclAST* decl_ptr; + DeclListAST* decl_list_ptr; + Vector* decl_vector_ptr; + + // TypeField + TypeFieldAST* type_field_ptr; + Vector* type_field_vector_ptr; + + // Type + TypeAST* type_ptr; + Vector* type_vector_ptr; + + // Formal Params + FormalParamAST* formal_param_ptr; + Vector* formal_param_vector_ptr; + + // Statements + StatementAST* statement_ptr; + StatementListAST* statement_list_ptr; + Vector* statement_vector_ptr; + + // Pairs + PairAST* pair_ptr; + PairListAST* pair_list_ptr; + + // Expressions + VarExprAST* var_expr_ptr; + ExprAST* expr_ptr; + Vector* expr_vector_ptr; +} + +%type type void type_or_void +%type types type_list + + // Formal Params +%type formal_param +%type formal_params formal_param_list + +%type ident field +%type ident_list idents + +%type statement if_statement +%type statement_list +%type statements + +%type decl +%type decl_list +%type decls + +%type type_members type_enums type_methods +%type type_member type_enum type_method + +%type var +%type expr literal enumeration +%type expr_list + +%type pair +%type pair_list pairs + +%token IDENT STRING NUMBER FLOATNUMBER LIT_BOOL VOID +%token IMBED IMBED_TYPE +%token CHIP THIS +%token ASSIGN DOUBLE_COLON DOT SEMICOLON COLON +%token GLOBAL_DECL MACHINE_DECL IN_PORT_DECL OUT_PORT_DECL +%token PEEK ENQUEUE COPY_HEAD CHECK_ALLOCATE CHECK_STOP_SLOTS +//%token DEQUEUE REMOVE_EARLY SKIP_EARLY PEEK_EARLY +%token DEBUG_EXPR_TOKEN DEBUG_MSG_TOKEN +%token ACTION_DECL TRANSITION_DECL TYPE_DECL STRUCT_DECL EXTERN_TYPE_DECL ENUM_DECL +%token TYPE_FIELD OTHER IF ELSE RETURN + +%token EQ NE '<' '>' LE GE NOT AND OR PLUS DASH STAR SLASH RIGHTSHIFT LEFTSHIFT + +%left OR +%left AND +%nonassoc EQ NE +%nonassoc '<' '>' GE LE +%left PLUS DASH +%left STAR SLASH +%nonassoc NOT +%nonassoc DOUBLE_COLON DOT '[' + +%% + +file: decl_list { g_decl_list_ptr = $1; } + +decl_list: decls { $$ = new DeclListAST($1); } + +decls: decl decls { $2->insertAtTop($1); $$ = $2; } + | { $$ = new Vector; } + ; + +decl: MACHINE_DECL '(' ident pair_list ')' '{' decl_list '}' { $$ = new MachineAST($3, $4, $7); } + | ACTION_DECL '(' ident pair_list ')' statement_list { $$ = new ActionDeclAST($3, $4, $6); } + | IN_PORT_DECL '(' ident ',' type ',' var pair_list ')' statement_list { $$ = new InPortDeclAST($3, $5, $7, $8, $10); } + | OUT_PORT_DECL '(' ident ',' type ',' var pair_list ')' SEMICOLON { $$ = new OutPortDeclAST($3, $5, $7, $8); } + | TRANSITION_DECL '(' ident_list ',' ident_list ',' ident pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, $7, $8, $10); } + | TRANSITION_DECL '(' ident_list ',' ident_list pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, NULL, $6, $8); } + | EXTERN_TYPE_DECL '(' type pair_list ')' SEMICOLON { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, NULL); } + | EXTERN_TYPE_DECL '(' type pair_list ')' '{' type_methods '}' { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, $7); } + | GLOBAL_DECL '(' type pair_list ')' '{' type_members '}' { $4->addPair(new PairAST("global", "yes"));$$ = new TypeDeclAST($3, $4, $7); } + | STRUCT_DECL '(' type pair_list ')' '{' type_members '}' { $$ = new TypeDeclAST($3, $4, $7); } + | ENUM_DECL '(' type pair_list ')' '{' type_enums '}' { $4->addPair(new PairAST("enumeration", "yes")); $$ = new EnumDeclAST($3, $4, $7); } + | type ident pair_list SEMICOLON { $$ = new ObjDeclAST($1, $2, $3); } + | type ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // non-void function + | void ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // void function + | type ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // non-void function + | void ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // void function + ; + +// Type fields + +type_members: type_member type_members { $2->insertAtTop($1); $$ = $2; } + | { $$ = new Vector; } + ; + +type_member: type ident pair_list SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, $3, NULL); } + | type ident ASSIGN expr SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, new PairListAST(), $4); } + ; + +// Methods +type_methods: type_method type_methods { $2->insertAtTop($1); $$ = $2; } + | { $$ = new Vector; } + ; + +type_method: type_or_void ident '(' type_list ')' pair_list SEMICOLON { $$ = new TypeFieldMethodAST($1, $2, $4, $6); } + ; + +// Enum fields +type_enums: type_enum type_enums { $2->insertAtTop($1); $$ = $2; } + | { $$ = new Vector; } + ; + +type_enum: ident pair_list SEMICOLON { $$ = new TypeFieldEnumAST($1, $2); } + ; + +// Type +type_list : types { $$ = $1; } + | { $$ = new Vector; } + ; + +types : type ',' types { $3->insertAtTop($1); $$ = $3; } + | type { $$ = new Vector; $$->insertAtTop($1); } + ; + +type: ident { $$ = new TypeAST($1); } + ; + +void: VOID { $$ = new TypeAST($1); } + ; + +type_or_void: type { $$ = $1; } + | void { $$ = $1; } + ; + +// Formal Param +formal_param_list : formal_params { $$ = $1; } + | { $$ = new Vector; } + ; + +formal_params : formal_param ',' formal_params { $3->insertAtTop($1); $$ = $3; } + | formal_param { $$ = new Vector; $$->insertAtTop($1); } + ; + +formal_param : type ident { $$ = new FormalParamAST($1, $2); } + ; + +// Idents and lists +ident: IDENT { $$ = $1; } ; + +ident_list: '{' idents '}' { $$ = $2; } + | ident { $$ = new Vector; $$->insertAtTop(*($1)); delete $1; } + ; + +idents: ident SEMICOLON idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; } + | ident ',' idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; } + | ident idents { $2->insertAtTop(*($1)); $$ = $2; delete $1; } + | { $$ = new Vector; } + ; + +// Pair and pair lists +pair_list: ',' pairs { $$ = $2; } + | { $$ = new PairListAST(); } + +pairs : pair ',' pairs { $3->addPair($1); $$ = $3; } + | pair { $$ = new PairListAST(); $$->addPair($1); } + ; + +pair : ident '=' STRING { $$ = new PairAST($1, $3); } + | ident '=' ident { $$ = new PairAST($1, $3); } + | STRING { $$ = new PairAST(new string("short"), $1); } + ; + +// Below are the rules for action descriptions + +statement_list: '{' statements '}' { $$ = new StatementListAST($2); } + ; + +statements: statement statements { $2->insertAtTop($1); $$ = $2; } + | { $$ = new Vector; } + ; + +expr_list: expr ',' expr_list { $3->insertAtTop($1); $$ = $3; } + | expr { $$ = new Vector; $$->insertAtTop($1); } + | { $$ = new Vector; } + ; + +statement: expr SEMICOLON { $$ = new ExprStatementAST($1); } + | expr ASSIGN expr SEMICOLON { $$ = new AssignStatementAST($1, $3); } + | ENQUEUE '(' var ',' type pair_list ')' statement_list { $$ = new EnqueueStatementAST($3, $5, $6, $8); } + | PEEK '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peek"); } +// | PEEK_EARLY '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peekEarly"); } + | COPY_HEAD '(' var ',' var pair_list ')' SEMICOLON { $$ = new CopyHeadStatementAST($3, $5, $6); } + | CHECK_ALLOCATE '(' var ')' SEMICOLON { $$ = new CheckAllocateStatementAST($3); } + | CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMICOLON { $$ = new CheckStopSlotsStatementAST($3, $5, $7); } + | if_statement { $$ = $1; } + | RETURN expr SEMICOLON { $$ = new ReturnStatementAST($2); } + ; + +if_statement: IF '(' expr ')' statement_list ELSE statement_list { $$ = new IfStatementAST($3, $5, $7); } + | IF '(' expr ')' statement_list { $$ = new IfStatementAST($3, $5, NULL); } + | IF '(' expr ')' statement_list ELSE if_statement { $$ = new IfStatementAST($3, $5, new StatementListAST($7)); } + ; + +expr: var { $$ = $1; } + | literal { $$ = $1; } + | enumeration { $$ = $1; } + | ident '(' expr_list ')' { $$ = new FuncCallExprAST($1, $3); } + + +// globally access a local chip component and call a method + | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $5, $8, $10, $12 ); } +// globally access a local chip component and access a data member + | THIS DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $5, $8, $10 ); } +// globally access a specified chip component and call a method + | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13, $15 ); } +// globally access a specified chip component and access a data member + | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13 ); } + + + | expr DOT field { $$ = new MemberExprAST($1, $3); } + | expr DOT ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); } + | type DOUBLE_COLON ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); } + | expr '[' expr_list ']' { $$ = new MethodCallExprAST($1, new string("lookup"), $3); } + | expr STAR expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr SLASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr PLUS expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr DASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr '<' expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr '>' expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr LE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr GE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr EQ expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr NE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr AND expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr OR expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr RIGHTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); } + | expr LEFTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); } +// | NOT expr { $$ = NULL; } // FIXME - unary not +// | DASH expr %prec NOT { $$ = NULL; } // FIXME - unary minus + | '(' expr ')' { $$ = $2; } + ; + +literal: STRING { $$ = new LiteralExprAST($1, "string"); } + | NUMBER { $$ = new LiteralExprAST($1, "int"); } + | FLOATNUMBER { $$ = new LiteralExprAST($1, "int"); } + | LIT_BOOL { $$ = new LiteralExprAST($1, "bool"); } + ; + +enumeration: ident ':' ident { $$ = new EnumExprAST(new TypeAST($1), $3); } + ; + +var: ident { $$ = new VarExprAST($1); } + ; + +field: ident { $$ = $1; } + ; + +%% + +extern FILE *yyin; + +DeclListAST* parse(string filename) +{ + FILE *file; + file = fopen(filename.c_str(), "r"); + if (!file) { + cerr << "Error: Could not open file: " << filename << endl; + exit(1); + } + g_line_number = 1; + g_file_name = filename; + yyin = file; + g_decl_list_ptr = NULL; + yyparse(); + return g_decl_list_ptr; +} + +extern "C" void yyerror(char* s) +{ + fprintf(stderr, "%s:%d: %s at %s\n", g_file_name.c_str(), g_line_number, s, yytext); + exit(1); +} + -- cgit v1.2.3