首页 文章

antlr4中的mincaml语法

提问于
浏览
2

我想在antlr4中编写mincaml解析器 . github(https://github.com/esumii/min-caml/blob/master/parser.mly) . 日本网站:http://esumii.github.io/min-caml/ .

这是antlr 4代码 .

grammar MinCaml;

simple_exp:                 #simpleExp
    | LPAREN exp RPAREN     #parenExp
    | LPAREN RPAREN         #emptyParen
    | BOOL                  #boolExpr
    | INT                   #intExpr
    | FLOAT                 #floatExpr
    | IDENT                 #identExpr
    | simple_exp DOT LPAREN exp RPAREN  #arrayGetExpr
    ;

exp :               #programExp
    | simple_exp    #simpleExpInExp
    | NOT exp       #notExp
    | MINUS exp     #minusExp
    | MINUS_DOT exp #minusFloatExp
    | left = exp op = (AST_DOT | SLASH_DOT) right = exp     #astSlashExp
    | left = exp op = (PLUS | MINUS | MINUS_DOT | PLUS_DOT) right = exp     #addSubExp
    | left = exp op = (EQUAL | LESS_GREATER | LESS | GREATER | LESS_EQUAL | GREATER_EQUAL) right = exp    #logicExp
    | IF condition = exp THEN thenExp = exp ELSE elseExp = exp      #ifExp
    | LET IDENT EQUAL exp IN exp    #letExp
    | LET REC fundef IN exp         #letRecExp
    | exp actual_args               #appExp
    | exp COMMA exp elems           #tupleExp
    | LET LPAREN pat RPAREN EQUAL exp IN exp        #tupleReadExp
    | simple_exp DOT LPAREN exp RPAREN LESS_MINUS exp   #putExp
    | exp SEMICOLON exp                                 #expSeqExp
    | ARRAY_CREATE simple_exp simple_exp                #arrayCreateExp
    ;

fundef:
    | IDENT formal_args EQUAL exp
    ;

formal_args:
    | IDENT formal_args
    | IDENT
    ;

actual_args:
    | actual_args simple_exp
    | simple_exp
    ;

elems:
    | COMMA exp elems
    | 
    ;

pat:
    | pat COMMA IDENT
    | IDENT COMMA IDENT
    ;

    LET : 'let';
    REC : 'rec';
    IF : 'if';
    THEN : 'then';
    ELSE : 'else';
    IN : 'in';
    IDENT : '_' | [a-z][a-zA-Z0-9_]+;
    ARRAY_CREATE : 'Array.create';
    LPAREN : '(';
    RPAREN : ')';
    BOOL : 'true' 'false';
    NOT : 'not';
    INT : ['1'-'9'] (['0'-'9'])*;
    FLOAT : (['0'-'9'])+ ('.' (['0'-'9'])*)? (['e', 'E'] (['+', '-'])? (['0'-'9'])+)?;
    MINUS : '-';
    PLUS : '+';
    MINUS_DOT : '-.';
    PLUS_DOT : '+.';
    AST_DOT : '*.';
    SLASH_DOT : '/.';
    EQUAL : '=';
    LESS_GREATER : '';
    LESS_EQUAL : '=';
    LESS : '';
    DOT : '.';
    LESS_MINUS : ' skip ; // toss out whitespace
    COMMENT : '(*' .*? '*)' -> skip;

但我在规则exp和实际args上遇到以下错误 .

error(148):MinCaml.g4:13:0:左递归规则exp包含一个左递归替代,后面可以跟空字符串错误(148):MinCaml.g4:41:0:左递归规则actual_args包含一个左递归替代,后面可以跟空字符串

但我没有看到两个规则都有空字符串的可能性 . 或者我错了?这段代码有什么问题?

1 回答

  • 0

    exp 规则的第一行(实际上是每条规则)都是可能出现的问题:

    exp :               #programExp
    

    标准规则表是

    r: alt1 | alt2 | .... | altN ;
    

    语法中的 alt1 都是空的 . 空的alt "matches an empty string" .

    鉴于 elems 规则似乎具有故意空的alt,考虑到一般而言,具有空的alts的规则可能是有问题的 . 而不是使用空的alt,使父规则中的相应元素可选( ?* ) .

相关问题