我使用 ANTLR 版本 4 创建编译器。第一阶段是词法分析器部分。我创建了“CompilerLexer.g4”文件并将词法分析器规则放入其中。它工作正常。
CompilerLexer.g4:
lexer grammar CompilerLexer;
INT : 'int' ; //1
FLOAT : 'float' ; //2
BEGIN : 'begin' ; //3
END : 'end' ; //4
To : 'to' ; //5
NEXT : 'next' ; //6
REAL : 'real' ; //7
BOOLEAN : 'bool' ; //8
.
.
.
NOTEQUAL : '!=' ; //46
AND : '&&' ; //47
OR : '||' ; //48
POW : '^' ; //49
ID : [a-zA-Z]+ ; //50
WS
: ' ' -> channel(HIDDEN) //50
;
现在是第 2 阶段的时间,即解析器。我创建了“CompilerParser.g4”文件并将语法放入其中,但有许多警告和错误。
CompilerParser.g4:
parser grammar CompilerParser;
options { tokenVocab = CompilerLexer; }
STATEMENT : EXPRESSION SEMIC
| IFSTMT
| WHILESTMT
| FORSTMT
| READSTMT SEMIC
| WRITESTMT SEMIC
| VARDEF SEMIC
| BLOCK
;
BLOCK : BEGIN STATEMENTS END
;
STATEMENTS : STATEMENT STATEMENTS*
;
EXPRESSION : ID ASSIGN EXPRESSION
| BOOLEXP
;
RELEXP : MODEXP (GT | LT | EQUAL | NOTEQUAL | LE | GE | AND | OR) RELEXP
| MODEXP
;
.
.
.
VARDEF : (ID COMA)* ID COLON VARTYPE
;
VARTYPE : INT
| FLOAT
| CHAR
| STRING
;
compileUnit
: EOF
;
警告和错误:
- implicit definition of token 'BLOCK' in parser
- implicit definition of token 'BOOLEXP' in parser
- implicit definition of token 'EXP' in parser
- implicit definition of token 'EXPLIST' in parser
- lexer rule 'BLOCK' not allowed in parser
- lexer rule 'EXP' not allowed in parser
- lexer rule 'EXPLIST' not allowed in parser
- lexer rule 'EXPRESSION' not allowed in parser
有许多这样的警告和错误。这是什么原因?
一般问题:使用组合语法和分别使用词法分析器和解析器有什么区别?应该如何加入单独的语法和词法分析器文件?
最佳答案
词法分析器规则以大写字母开头,解析器规则以小写字母开头。在解析器语法中,您不能定义标记。由于 ANTLR 认为所有大写规则都是词法分析器规则,因此它会产生这些错误/警告。
编辑
user2998131 wrote:
General Questions: What is difference between using combined grammar and using lexer and parser separately?
将词法分析器和解析器规则分开将使事情井井有条。此外,在创建单独的词法分析器和解析器语法时,您不能(不小心)将文字标记放入解析器语法中,但需要在词法分析器语法中定义所有标记。这将使哪些词法分析器规则在其他规则之前得到匹配变得显而易见,并且您不能在重复出现的文字标记中输入任何错字:
grammar P;
r1 : 'foo' r2;
r2 : r3 'foo '; // added an accidental space after 'foo'
但是当你有解析器语法时,你就不会犯那个错误了。您将必须使用匹配“foo”的词法分析器规则:
parser grammar P
options { tokenVocab=L; }
r1 : FOO r2;
r2 : r3 FOO;
lexer grammar L;
FOO : 'foo';
user2998131 wrote:
How should join separate grammar and lexer files?
就像您在解析器语法中所做的那样:您在 options { ... }
block 中指向正确的 tokenVocab
。
请注意,您还可以导入语法,这是不同的:https://github.com/antlr/antlr4/blob/master/doc/grammars.md#grammar-imports
关于c# - 分别使用 ANTLR Parser 和 Lexer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24299214/