我是新来的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'

有什么问题?我已经重写了好几遍语法,但结果都不成功

推荐答案

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

剩下的问题是:

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

给定这两个lexer规则,输入20将始终成为RANGE令牌.这就是ANTLR生成令牌的简单方式:它try for each lexer规则匹配尽可能多的字符,当2个(或更多)lexer规则匹配相同的字符时,让第一个定义的那个"获胜".

解决方案:删除RANGE,并将解析器规则中的所有RANGE替换为NUMBER.然后,在解析之后,您可以执行一些语义判断,看看NUMBER在某些地方是否有效.您可以在ANTLR侦听器中执行此操作.

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

COMPLETION:
    DO: OUTPUT: "Some text"

并且给定了语法,我看不出您试图为这个输入匹配什么解析器规则.解析器规则completion:

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

一开始就缺少关键词COMPLETION:.这可能是一个解决方案:

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

...

COMPLETION : 'COMPLETION';

Csharp相关问答推荐

如何使用Microsoft Curve API从搜索的文件中获取内容(文本)?

如何将两个查询结果组合在C#ASP.NET MHC控制器中

是否可以将gltf转换为字节数组,然后将字节数组转换回文件?

当Visual Studio处于升级管理模式时,无法安装Torch运行时

LINQ无法翻译SQLFunctions方法

如何从HttpContext获取请求正文

try 在Blazor项目中生成html

在LINQ Where子句中使用新的DateTime

Blazor EventCallback<;MyType<;T>;>;

如何在Windows 11任务调度程序中每1分钟重复一次任务?

Rx.Net窗口内部可观测数据提前完成

try 使用C#ASP.NET收集WMI信息时访问被拒绝,但在PowerShell中工作

如何将字符串变量传递给JObject C#-无法加载文件或程序集';System.Text.Json

使用带有参数和曲面的注入失败(&Q;)

交替的奇数

什么类型的对象存储在大对象堆(LOH)中

当try 测试具有协变返回类型的抽象属性时,类似功能引发System.ArgumentException

JsonPath在Newtonsoft.Json';S实现中的赋值

发布.NET 8 Blazor WebAssembly独立应用程序以进行静态站点部署

我是否应该注销全局异常处理程序