- /*
- * Make sure to run antlr.Tool on the lexer.g file first!
- */
- options {
- mangleLiteralPrefix = "TK_";
- language = "Sather";
- }
- {
- class MAIN is
- main ( args : ARRAY{STR} ) is
- if ( args.size < 2 ) then
- #OUT + "usage " + args[0] + " <filename>n";
- return;
- end;
- f : IFSTREAM := IFSTREAM::open_for_read( args[1] );
- if ( void(f) ) then
- #OUT + "file "" + args[1] + "" not foundn";
- return;
- end;
- protect
- lexer ::= #TINYC_LEXER{ANTLR_COMMON_TOKEN}( f );
- parser ::= #TINYC_PARSER{ANTLR_COMMON_TOKEN,ANTLR_COMMON_AST}( lexer );
- parser.program;
- t ::= parser.ast;
- #OUT + t.str_list + "n";
- when $ANTLR_RECOGNITION_EXCEPTION then
- #ERR + "exception: " + exception.str + "n";
- end;
- end;
- end;
- }
- class TINYC_PARSER extends Parser;
- options {
- importVocab=TINYC; // use vocab generated by lexer
- buildAST = true;
- }
- program
- : ( declaration )* EOF
- ;
- declaration
- : (variable) => variable
- | function
- ;
- declarator
- : id:ID
- | STAR id2:ID
- ;
- variable
- : type_ declarator SEMI
- ;
- function
- : type_ id:ID LPAREN
- (formalParameter (COMMA formalParameter)*)?
- RPAREN
- block
- ;
- formalParameter
- : type_ declarator
- ;
- type_: // "type" is keyword in Sather
- (
- TK_int
- | TK_char
- | id:ID
- )
- ;
- block
- : LCURLY ( statement )* RCURLY
- ;
- statement
- : (declaration) => declaration
- | expr SEMI
- | TK_if LPAREN expr RPAREN statement
- ( TK_else statement )?
- | TK_while LPAREN expr RPAREN statement
- | block
- ;
- expr: assignExpr
- ;
- assignExpr
- : aexpr (ASSIGN assignExpr)?
- ;
- aexpr
- : mexpr (PLUS mexpr)*
- ;
- mexpr
- : atom (STAR atom)*
- ;
- atom: ID
- | INT
- | CHAR_LITERAL
- | STRING_LITERAL
- ;