分别使用 ANTLR 解析器和词法分析器 [英] Using ANTLR Parser and Lexer Separatly

查看:37
本文介绍了分别使用 ANTLR 解析器和词法分析器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 ANTLR 版本 4 来创建编译器.第一阶段是词法分析器部分.我创建了CompilerLexer.g4"文件并将词法分析器规则放入其中.它工作正常.

CompilerLexer.g4:

<小时>

词法分析器语法CompilerLexer;INT : 'int' ;//1浮动:'浮动';//2开始:'开始';//3结束:'结束';//4到 : '到' ;//5下一个:'下一个';//6真实:'真实';//7布尔:'布尔';//8...注意: '!=' ;//46AND : '&&';//47或:'||';//48战俘:'^';//49ID : [a-zA-Z]+ ;//50WS: ' ' ->频道(隐藏)//50;

<小时>

现在是解析器阶段 2 的时候了.我创建了CompilerParser.g4"文件并将语法放入其中,但有许多警告和错误.

CompilerParser.g4:

<小时>

解析器语法CompilerParser;选项 { tokenVocab = CompilerLexer;}声明:表达半导体|IFSTMT|同时|福斯特|读取半导体|写字半导体|瓦德夫半导体|堵塞;块:开始语句结束;声明:声明 声明*;表达式:ID 分配表达式|布尔经验;RELEXP : MODEXP (GT | LT | EQUAL | NOTEQUAL | LE | GE | AND | OR) RELEXP|模式;...VARDEF : (ID COMA)* ID COLON VARTYPE;变量类型:INT|漂浮|字符|细绳;编译单元:EOF;

<小时>

警告和错误:

<块引用>
  • 在解析器中隐式定义标记BLOCK"
  • 在解析器中隐式定义标记BOOLEXP"
  • 在解析器中隐式定义标记EXP"
  • 在解析器中隐式定义标记EXPLIST"
  • 解析器中不允许使用词法规则BLOCK"
  • 解析器中不允许使用词法规则EXP"
  • 解析器中不允许使用词法规则EXPLIST"
  • 解析器中不允许使用词法规则EXPRESSION"

有很多这样的警告和错误.是什么原因?

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

解决方案

词法规则以大写字母开头,解析器规则以小写字母开头.在解析器语法中,您不能定义标记.而且由于 ANTLR 认为您所有的大写规则都是词法分析器规则,因此会产生这些错误/警告.

编辑

<块引用>

user2998131 写道:

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

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

语法P;r1 : 'foo' r2;r2 : r3 'foo';//在 'foo' 后面添加了一个意外的空格

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

解析器语法P选项 { tokenVocab=L;}r1:FOO r2;r2 : r3 FOO;词法语法 L;FOO : '富';

<块引用>

user2998131 写道:

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

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

请注意,您也可以导入语法,这是不同的:https://github.com/antlr/antlr4/blob/master/doc/grammars.md#grammar-imports

I used ANTLR version 4 for creating compiler.First Phase was the Lexer part. I created "CompilerLexer.g4" file and putted lexer rules in it.It works fine.

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
;


Now it is time for phase 2 which is the parser.I created "CompilerParser.g4" file and putted grammars in it but have dozens warning and errors.

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
;


Warning and errors:

  • 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

Have dozens of these warning and errors. What is the cause?

General Questions: What is difference between using combined grammar and using lexer and parser separately? How should join separate grammar and lexer files?

解决方案

Lexer rules start with a capital letter, and parser rules start with a lowercase letter. In a parser grammar, you can't define tokens. And since ANTLR thinks all your upper-cased rules lexer rules, it produces theses errors/warning.

EDIT

user2998131 wrote:

General Questions: What is difference between using combined grammar and using lexer and parser separately?

Separating the lexer and parser rules will keeps things organized. Also, when creating separate lexer and parser grammars, you can't (accidentally) put literal tokens inside your parser grammar but will need to define all tokens in your lexer grammar. This will make it apparent which lexer rules get matched before others, and you can't make any typo's inside recurring literal tokens:

grammar P;

r1 : 'foo' r2;

r2 : r3 'foo '; // added an accidental space after 'foo'

But when you have a parser grammar, you can't make that mistake. You will have to use the lexer rule that matches '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?

Just like you do in your parser grammar: you point to the proper tokenVocab inside the options { ... } block.

Note that you can also import grammars, which is something different: https://github.com/antlr/antlr4/blob/master/doc/grammars.md#grammar-imports

这篇关于分别使用 ANTLR 解析器和词法分析器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆