分别使用ANTLR Parser和Lexer

use*_*131 8 c# grammar lexer antlr4

我使用ANTLR版本4来创建编译器.第一阶段是Lexer部分.我创建了"CompilerLexer.g4"文件并在其中推出了lexer规则.它工作正常.

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
;
Run Code Online (Sandbox Code Playgroud)

现在是第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
;
Run Code Online (Sandbox Code Playgroud)

警告和错误:

  • 解析器中令牌'BLOCK'的隐式定义
  • 解析器中标记'BOOLEXP'的隐式定义
  • 解析器中令牌'EXP'的隐式定义
  • 解析器中标记'EXPLIST'的隐式定义
  • 解析器中不允许使用词法分析器"BLOCK"
  • 解析器中不允许使用词法规则"EXP"
  • 解析器中不允许使用词法分析器'EXPLIST'
  • 解析器中不允许使用词法分析器'EXPRESSION'

有几十个这些警告和错误.原因是什么?

一般问题:使用组合语法和分别使用词法分析器和解析器有什么区别?应该如何加入单独的语法和词法分析器文件?

Bar*_*ers 9

Lexer规则以大写字母开头,解析器规则以小写字母开头.在解析器语法中,您无法定义标记.而且由于ANTLR认为你所有的上层规则都是规则,它会产生错误/警告.

编辑

user2998131写道:

一般问题:使用组合语法和分别使用词法分析器和解析器有什么区别?

分离词法分析器和解析器规则将使事情井然有序.此外,在创建单独的词法分析器和解析器语法时,您不能(意外地)将文字标记置于解析器语法中,但需要在词法分析器语法中定义所有标记.这将显示哪些词法分析器规则在其他规则之前匹配,并且您不能在重复的文字标记内输入任何拼写错误:

grammar P;

r1 : 'foo' r2;

r2 : r3 'foo '; // added an accidental space after 'foo'
Run Code Online (Sandbox Code Playgroud)

但是当你有一个解析器语法时,你就不会犯这个错误.您将不得不使用匹配'foo'的词法分析器规则:

parser grammar P

options { tokenVocab=L; }

r1 : FOO r2;

r2 : r3 FOO;


lexer grammar L;

FOO : 'foo';
Run Code Online (Sandbox Code Playgroud)

user2998131写道:

应该如何加入单独的语法和词法分析器文件?

就像你在解析器语法中所做的那样:你指向块中的正确tokenVocab内容options { ... }.

请注意,您还可以导入语法,这是不同的:https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Grammar+Structure#GrammarStructure-GrammarImports

  • 是的,“组合”语法在 1 个语法文件中同时具有词法分析器规则和解析器规则。在解析器语法中使用“tokenVocab”(您必须这样做)将使您可以将解析器语法指向解析器语法所需的词法分析器规则。除此之外,导入语法是组合解析器或词法分析器语法可以做的事情。 (2认同)