c# - 分别使用 ANTLR Parser 和 Lexer

标签 c# grammar antlr4 lexer

我使用 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/

相关文章:

html - 需要一个用于 HTML 的简单 Bison 语法

python - 如何在 Python 中使用带有 pocketsphinx 的 jsgf 语法文件检索单词的规则名称?

java - ANTLR4 TokenStream,getText方法

antlr - 从解析器切换 Antlr 词法分析器模式

c# - 在应用程序启动时禁用 Windows 服务

c# - task.Status == RanToCompletion 和 task.IsCompleted 的比较

c# - 为什么我不能写 Nullable<Nullable<int>>?

c - C语法中的NULL

c# - ASP.NET Entity Framework Code First 环境间迁移过程

java - 如何为两个相似的ANTLR4语法实现共享访问者?