Antlr4 词法分析器采用了错误的规则
Antlr4 lexer takes wrong rule
我的语言具有可以无参数或带参数的命令,以及一个 "if" 关键字:
cmd1 // parameter-less command
cmd2 a word // with parameter: "a word" - it starts with first non-WS char
if cmd3 // if, not a command, followed by parameter-less command
cmd4 if text // command with parameter: "if text"
"if" 仅当它是该行中的第一个非 WS 字符串时才被识别为 if
(现在让我们忽略注释...)
这些是我的语法规则:
语法 TestFlow;
// Parser Rules:
root: (lineComment | ifStat | cmd )* EOF;
lineComment : LC;
ifStat : IF;
cmd : CMD;
// Lexer Rules:
LC : '//' ~([\n\r\u2028\u2029])* -> channel(HIDDEN); // line comment
IF : 'if';
CMD : [-_a-zA-Z0-9]+ GAP LINE
| [-_a-zA-Z0-9]+
;
fragment GAP : [ \t]+;
fragment LINE : ~([\n\r\u2028\u2029])*;
但是我的词法分析器将第 3 行识别为 CMD
:if cmd3
,而不是我需要的 if
后跟 cmd3
。
我的错误是什么?如何解决?
您的示例中似乎没有定义语法的解析器规则。这意味着没有规则指示查找 'if' 和命令。
你的话是怎么回事:
But my lexer identifies 3rd line as a CMD: if cmd3, and not as if followed by cmd3 as I need
词法分析器规则 CMD 中的第一个选项查找一个或多个字符 ("if"),然后是 space ' ',然后是 LINE (cmd3)。
因此,输入 "if cmd3" 它匹配整行,这正是您告诉它要做的!
我可以根据个人经验告诉您,即使是一门简单的语言,您也可以通过后退一步并复习一些示例语法来快速学习 很多,这如果我现在是你,我会这样做以避免沮丧。我 高度 推荐 www.pragprog.com 的 Antlr4 参考书以及 antlr 网站。
已更新
我想这可能是您感兴趣的内容:
grammar myGrammar;
root : statement NEWLINE
| comment NEWLINE
;
statement : ifStat (LC)?
| cmdStat (LC)?
;
ifStat : IF cmdStat;
cmdStat : cmd (args)*;
cmd : CMD;
args : LINE;
CMD : [-_a-zA-Z0-9]+ GAP LINE
| [-_a-zA-Z0-9]+
;
fragment GAP : [ \t]+;
fragment LINE : ~([\n\r\u2028\u2029])*;
NEWLINE : ('\r')?'\n';
同样,我必须说,如果您读过这本书(我读过),这可能会给您解析器(而不是词法分析器)的预期响应。
ifStat 是可选的(可能存在也可能不存在,具体取决于您的测试用例),总会有一个 cmd,它后面可能有也可能没有行注释。试试这个,看看它是否有帮助。祝你好运!
只是小小的一行,让一切变得完美:在我的 MyParser.g4
中,只需输入:
options { tokenVocab = MyLexer; }
紧接着 parser grammar MYParser;
...
为了找到这个小细节浪费了很多时间...:-(
(少数)其他不知道发生了什么的人的帖子,只是为了最终找到这个解决方案:
ANTLR: Lexer does not recognize token
mismatched Input when lexing and parsing with modes
我的语言具有可以无参数或带参数的命令,以及一个 "if" 关键字:
cmd1 // parameter-less command
cmd2 a word // with parameter: "a word" - it starts with first non-WS char
if cmd3 // if, not a command, followed by parameter-less command
cmd4 if text // command with parameter: "if text"
"if" 仅当它是该行中的第一个非 WS 字符串时才被识别为 if
(现在让我们忽略注释...)
这些是我的语法规则: 语法 TestFlow;
// Parser Rules:
root: (lineComment | ifStat | cmd )* EOF;
lineComment : LC;
ifStat : IF;
cmd : CMD;
// Lexer Rules:
LC : '//' ~([\n\r\u2028\u2029])* -> channel(HIDDEN); // line comment
IF : 'if';
CMD : [-_a-zA-Z0-9]+ GAP LINE
| [-_a-zA-Z0-9]+
;
fragment GAP : [ \t]+;
fragment LINE : ~([\n\r\u2028\u2029])*;
但是我的词法分析器将第 3 行识别为 CMD
:if cmd3
,而不是我需要的 if
后跟 cmd3
。
我的错误是什么?如何解决?
您的示例中似乎没有定义语法的解析器规则。这意味着没有规则指示查找 'if' 和命令。
你的话是怎么回事:
But my lexer identifies 3rd line as a CMD: if cmd3, and not as if followed by cmd3 as I need
词法分析器规则 CMD 中的第一个选项查找一个或多个字符 ("if"),然后是 space ' ',然后是 LINE (cmd3)。 因此,输入 "if cmd3" 它匹配整行,这正是您告诉它要做的!
我可以根据个人经验告诉您,即使是一门简单的语言,您也可以通过后退一步并复习一些示例语法来快速学习 很多,这如果我现在是你,我会这样做以避免沮丧。我 高度 推荐 www.pragprog.com 的 Antlr4 参考书以及 antlr 网站。
已更新 我想这可能是您感兴趣的内容:
grammar myGrammar;
root : statement NEWLINE
| comment NEWLINE
;
statement : ifStat (LC)?
| cmdStat (LC)?
;
ifStat : IF cmdStat;
cmdStat : cmd (args)*;
cmd : CMD;
args : LINE;
CMD : [-_a-zA-Z0-9]+ GAP LINE
| [-_a-zA-Z0-9]+
;
fragment GAP : [ \t]+;
fragment LINE : ~([\n\r\u2028\u2029])*;
NEWLINE : ('\r')?'\n';
同样,我必须说,如果您读过这本书(我读过),这可能会给您解析器(而不是词法分析器)的预期响应。 ifStat 是可选的(可能存在也可能不存在,具体取决于您的测试用例),总会有一个 cmd,它后面可能有也可能没有行注释。试试这个,看看它是否有帮助。祝你好运!
只是小小的一行,让一切变得完美:在我的 MyParser.g4
中,只需输入:
options { tokenVocab = MyLexer; }
紧接着 parser grammar MYParser;
...
为了找到这个小细节浪费了很多时间...:-(
(少数)其他不知道发生了什么的人的帖子,只是为了最终找到这个解决方案:
ANTLR: Lexer does not recognize token
mismatched Input when lexing and parsing with modes