为什么我在 ANTLR4 中收到“输入不匹配”错误?

问题描述 投票:0回答:1

我是 ANTLR 的新手。我正在为 GURU 语言开发一个解析器。我写了一个语法并决定在网站上查看:site 我不明白为什么会出现错误。

这是我的语法:

grammar Guru;

/*
    PARSER RULES
 */

expertSystem : definition initialization completion rules variables EOF;

// Defenition
definition : GOAL ':' expertiseVariable;

// Initialization
initialization : INITIAL ':' (output | assignment | input)+;

// Completion
completion : DO ':' (assignment | output)+;

// Rules
rules : (rule)+;

rule : RULE ':' ruleName
    (auxiliaryElement)* (ready)* 
    IF ':' premise 
    THEN ':' conclusion
    (reason)* (usedVariables)*;

ruleName : IDENTIFIER;

auxiliaryElement : priority | cost | test | comment;
priority : PRIORITY ':' RANGE;
cost : COST ':' RANGE;
test : TEST ':' testValue;
testValue : 'S' | 'E' | 'P';
comment : COMMENT ':' text;

ready : READY ':' (readyCommand)+;
readyCommand : output | assignment;

// TODO: LOGOPERATOR
premise : andExpression;
andExpression : orExpression ('AND' orExpression)*;
orExpression : atomicExpression ('OR' atomicExpression)*;
atomicExpression : '(' premise ')' | comparisonExpression;
comparisonExpression : comparisonOperand COMOPERATOR comparisonOperand;
comparisonOperand : expertiseVariable | value | (function '(' expertiseVariable ')');

conclusion : (assignment)+;

reason : REASON ':' text;

usedVariables : needs | changes;
needs : NEEDS ':' '{' expertiseVariable (',' expertiseVariable)* '}';
changes : CHANGES ':' '{' expertiseVariable (',' expertiseVariable)* '}';

// Variables
variables : (variable)+;
variable : VAR ':' expertiseVariable (variableCommand)*;

variableCommand : find | label | when | cfType | rigor | limit;

find : FIND ':' (findCommand)+;
findCommand : assignment | input;

label : LABEL ':' text;

when : WHEN ':' whenValue;
whenValue : 'F' | 'L' | 'N';

cfType : CFTYPE ':' cfTypeValue cfTypeValue;
cfTypeValue : 'M' | 'P';

rigor : RIGOR ':' rigorValue;
rigorValue : 'M' | 'C' | 'A';

limit : LIMIT ':' NUMBER;

// General rules
output : OUTPUT ':' text;

assignment : expertiseVariable '=' value;

input : INPUT ':' expertiseVariable TYPE ':' TYPES WITH ':' text;

expertiseVariable : IDENTIFIER;

function : IDENTIFIER;

value : STRING | NUMBER;

text: STRING;

/*
    LEXER RULES
 */

GOAL : 'GOAL';
INITIAL : 'INITIAL';
DO : 'DO';
RULE : 'RULE';
IF : 'IF';
THEN : 'THEN';
PRIORITY : 'PRIORITY';
COST: 'COST';
TEST: 'TEST';
COMMENT : 'COMMENT';
READY : 'READY';
REASON : 'REASON';
NEEDS : 'NEEDS';
CHANGES : 'CHANGES';
VAR : 'VAR';
FIND : 'FIND';
LABEL : 'LABEL';
WHEN : 'WHEN';
CFTYPE : 'CFTYPE';
RIGOR : 'RIGOR';
LIMIT : 'LIMIT';
OUTPUT : 'OUTPUT';
INPUT : 'INPUT';
TYPE : 'TYPE';
WITH : 'WITH';

IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]*;
STRING : '"' ~["]* '"';
RANGE : [1-9] [0-9]? | '100';
NUMBER : '0' | [1-9][0-9]*;
TYPES : 'NUM' | 'STRING' | 'REAL';
LOGOPERATOR : 'AND' | 'OR';
COMOPERATOR : '>' | '<' | '>=' | '<=' | '==';

WS : [ \t\r\n]+ -> skip;

这是我想检查的文字:

GOAL: RESH
INITIAL: 
    OUTPUT: "Some text"
COMPLETION:
    DO: OUTPUT: "Some text"
RULE: R1
IF: RESH < 20
THEN: RESH = 20
VAR: RESH

以下是它产生的错误:

1:4 token recognition error at: ':'
2:7 token recognition error at: ':'
3:10 token recognition error at: ':'
3:12 token recognition error at: '"'
3:22 token recognition error at: '"'
4:10 token recognition error at: ':'
5:6 token recognition error at: ':'
5:14 token recognition error at: ':'
5:16 token recognition error at: '"'
5:26 token recognition error at: '"'
6:4 token recognition error at: ':'
7:2 token recognition error at: ':'
7:9 token recognition error at: '<'
8:4 token recognition error at: ':'
9:3 token recognition error at: ':'
1:0 mismatched input 'GOAL' expecting 'GOAL'

问题是什么?我已经把语法重写了好几次了,结果还是不成功

c# antlr antlr4
1个回答
0
投票

大多数错误源于您没有清除 ANTLR 实验室“词法分析器选项卡”中的规则。当你这样做时,许多错误就会消失。

剩下的问题是:

RANGE : [1-9] [0-9]? | '100';
NUMBER : '0' | [1-9][0-9]*;

考虑到这 2 个词法分析器规则,输入

20
将始终成为
RANGE
标记。这就是 ANTLR 生成标记的方式:它尝试为每个词法分析器规则匹配尽可能多的字符,并且当 2 个(或更多)词法分析器规则匹配相同的字符时,让第一个定义的规则“获胜”。

解决方案:删除

RANGE
并将解析器规则中的所有
RANGE
替换为
NUMBER
。然后在解析之后,您可以执行一些语义检查来查看
NUMBER
在某些地方是否有效。您可以在 ANTLR 侦听器中执行此操作。

第二个问题是解析器无法识别输入:

COMPLETION:
    DO: OUTPUT: "Some text"

考虑到语法,我看不出您试图为此输入匹配什么解析器规则。解析器规则

completion
:

completion : DO ':' (assignment | output)+;

似乎缺少关键字

COMPLETION
和开头的
:
。这可能是一个解决方案:

completion : COMPLETION ':' DO ':' (assignment | output)+;

...

COMPLETION : 'COMPLETION';
© www.soinside.com 2019 - 2024. All rights reserved.