无法在非组合语法中为字符串文字创建隐式标记



so为计算器找到了一个不错的语法,并从这里复制了一些小的更改:https://dexvis.wordpress.com/2012/11/22/a-tale-of-two-grammars/

我有两个文件:Parser和Lexer。看起来像这样:

    parser grammar Parser;
options{
    language = Java;
    tokenVocab = Lexer;
}
// PARSER
program : ((assignment|expression) ';')+;
assignment : ID '=' expression;
expression
    : '(' expression ')'                # parenExpression
    | expression ('*'|'/') expression   # multOrDiv
    | expression ('+'|'-') expression   # addOrSubtract
    | 'print' arg (',' arg)*            # print
    | STRING                            # string
    | ID                                # identifier
    | INT                               # integer;
arg : ID|STRING;    

和Lexer:

    lexer grammar WRBLexer;
STRING : '"' (' '..'~')* '"';
ID     : ('a'..'z'|'A'..'Z')+;
INT    : '0'..'9'+;
WS     : [ tnr]+ -> skip ;

基本上只是将Lexer和Parser拆分为两个文件。但当我试图保存时,我会收到一些错误:

error(126): Parser.g4:9:35: cannot create implicit token for string literal in non-combined grammar: ';'
error(126): Parser.g4:11:16: cannot create implicit token for string literal in non-combined grammar: '='
error(126): Parser.g4:2:13: cannot create implicit token for string literal in non-combined grammar: '('
error(126): Parser.g4:2:28: cannot create implicit token for string literal in non-combined grammar: ')'
error(126): Parser.g4:3:10: cannot create implicit token for string literal in non-combined grammar: 'print'
error(126): Parser.g4:3:23: cannot create implicit token for string literal in non-combined grammar: ','
error(126): Parser.g4:9:37: cannot create implicit token for string literal in non-combined grammar: '*'
error(126): Parser.g4:9:41: cannot create implicit token for string literal in non-combined grammar: '/'
error(126): Parser.g4:10:47: cannot create implicit token for string literal in non-combined grammar: '+'
error(126): Parser.g4:10:51: cannot create implicit token for string literal in non-combined grammar: '-'
10 error(s)

希望有人能帮我。

向致以最良好的问候

解析器语法中的所有文本标记:'*''/'等都需要在lexer语法中定义:

lexer grammar WRBLexer;
ADD : '+';
MUL : '*';
...

然后在语法分析器中,你会做:

expression
    : ...
    | expression (MUL|DIV) expression   # multOrDiv
    | expression (ADD|SUB) expression   # addOrSubtract
    | ...
    ;

由于您编写了两个文件。

你所有的符号,必须写在Lexer文件中。

我建议你这样做:

在Lexer文件中:

STRING : '"' (' '..'~')* '"';
ID     : ('a'..'z'|'A'..'Z')+;
INT    : '0'..'9'+;
WS     : [ tnr]+ -> skip ;
ADD_SUB: '+' | '-';
MUL_DIV: '*' | '/';
COMMA  : ',';
PRINT  : 'print';
Lb     : '(';
Rb     : ')';
COLON  : ';';
EQUAL  : '=';

和你的解析器:

parser grammar Parser;
options{
    language = Java;
    tokenVocab = Lexer;
}
// PARSER
program : ((assignment|expression) COLON)+;
assignment : ID EQUAL expression;
expression
    : Lb expression Rb                # parenExpression
    | expression MUL_DIV expression   # multOrDiv
    | expression ADD_SUB expression   # addOrSubtract
    | PRINT arg (COMMA arg)*            # print
    | STRING                            # string
    | ID                                # identifier
    | INT                               # integer
;
arg : ID|STRING; 

实际上,在规则中编写文字标记是可以的。您可以命名文字标记。例如,

expr: expr op=('*' | '/') expr  # binaryExpr
    | expr op=('+' | '-') expr  # binaryExpr
    | Number                    # number
    ;
Number: blah blah ;
Star : '*';
Div  : '/';
Plus : '+';
Minus: '-';

您可以按照如下方式编写侦听器:

class BinaryExpr {
    public enum BinaryOp {
        // ...
    }
    // ...
}
public class MyListener extends YourGrammarBaseListener {
    @Override
    public void exitBinaryExpr(YourGrammarParser.BinaryExprContext ctx) {
        BinaryExpr.BinaryOp op;
        switch (ctx.op.getType()) {
            case YourGrammarParser.Star:  op = BinaryExpr.BinaryOp.MUL; break;
            case YourGrammarParser.Div:   op = BinaryExpr.BinaryOp.DIV; break;
            case YourGrammarParser.Plus:  op = BinaryExpr.BinaryOp.ADD; break;
            case YourGrammarParser.Minus: op = BinaryExpr.BinaryOp.SUB; break;
            default: throw new RuntimeException("Unknown binary op.");
        }
        // ...
    }
}

相关内容

  • 没有找到相关文章

最新更新