Antlr4 用于简单命令处理器的Lexer和Parser规则
我正在尝试为遗留语言构建一个简单的命令处理器 我正在尝试使用C#使用antlr4版本“ANTLR”,“4.6.6”) 我无法在一种情况下取得进展,其中有几种情况 以下示例显示了命令PKS的各种示例调用Antlr4 用于简单命令处理器的Lexer和Parser规则,antlr4,Antlr4,我正在尝试为遗留语言构建一个简单的命令处理器 我正在尝试使用C#使用antlr4版本“ANTLR”,“4.6.6”) 我无法在一种情况下取得进展,其中有几种情况 以下示例显示了命令PKS的各种示例调用 PKS 我无法解决的情况是PKS命令后跟文件名 Command: PKS (block (line (expr (command PKS)) (eol \r\n)) <EOF>) Command: PKS? (block (line (expr (command PKS) (quer
PKS
我无法解决的情况是PKS命令后跟文件名
Command:
PKS
(block (line (expr (command PKS)) (eol \r\n)) <EOF>)
Command:
PKS?
(block (line (expr (command PKS) (query ?)) (eol \r\n)) <EOF>)
Command:
PKSFILENAME
line 1:0 mismatched input 'PKSFILENAME' expecting COMMAND
(block PKSFILENAME \r\n)
Command:
从lexer:
COMMAND : PKS;
PKS :'PKS' ;
QUERY : '?'
;
fragment LETTER : [A-Z];
fragment DIGIT : [0-9];
fragment UNDER : [_];
TEXT : (LETTER) (LETTER|DIGIT|UNDER)* ;
这里的主要问题是,您的
TEXT
规则也与PKS
应该匹配的内容相匹配。由于PKStext\u是一个文件名
可以完全与TEXT
规则匹配,因此它比PKS
规则更可取,即使它在语法中出现在第一位(如果两条规则匹配相同的输入,则第一条规则获胜)
要解决该问题,您有两个选项:
TEXT
规则以明确排除“PKS”作为有效输入Parser error (5, 1): extraneous input 'PKStext_that_is_a_filename' expecting {<EOF>, COMMAND, EOL}
Tokens:
[@0,0:2='PKS',<1>,1:0]
[@1,3:3='\n',<8>,1:3]
[@2,4:4='\n',<8>,2:0]
[@3,5:7='PKS',<1>,3:0]
[@4,8:8='?',<3>,3:3]
[@5,9:9='\n',<8>,3:4]
[@6,10:10='\n',<8>,4:0]
[@7,11:36='PKStext_that_is_a_filename',<7>,5:0]
[@8,37:37='\n',<8>,5:26]
[@9,38:37='<EOF>',<-1>,6:0]
以下是我使用的语法:
grammar Example;
start: block;
block: line+ EOF;
line: expr? eol;
expr: command (file | listOfDouble | query)?;
command: COMMAND;
query: QUERY;
file: TEXT;
eol: EOL;
listOfDouble: DOUBLE (COMMA DOUBLE)*;
COMMAND: PKS;
PKS: 'PKS';
QUERY: '?';
fragment LETTER: [a-zA-Z];
fragment DIGIT: [0-9];
fragment UNDER: [_];
COMMA: ',';
DOUBLE: DIGIT+ (DOT DIGIT*)?;
DOT: '.';
TEXT: LETTER (LETTER | DIGIT | UNDER)*;
EOL: [\n\r];
以及生成的可视化解析树:
COMMAND : PKS;
PKS :'PKS' ;
QUERY : '?'
;
fragment LETTER : [A-Z];
fragment DIGIT : [0-9];
fragment UNDER : [_];
TEXT : (LETTER) (LETTER|DIGIT|UNDER)* ;
Parser error (5, 1): extraneous input 'PKStext_that_is_a_filename' expecting {<EOF>, COMMAND, EOL}
Tokens:
[@0,0:2='PKS',<1>,1:0]
[@1,3:3='\n',<8>,1:3]
[@2,4:4='\n',<8>,2:0]
[@3,5:7='PKS',<1>,3:0]
[@4,8:8='?',<3>,3:3]
[@5,9:9='\n',<8>,3:4]
[@6,10:10='\n',<8>,4:0]
[@7,11:36='PKStext_that_is_a_filename',<7>,5:0]
[@8,37:37='\n',<8>,5:26]
[@9,38:37='<EOF>',<-1>,6:0]
PKS
PKS?
PKStext_that_is_a_filename
grammar Example;
start: block;
block: line+ EOF;
line: expr? eol;
expr: command (file | listOfDouble | query)?;
command: COMMAND;
query: QUERY;
file: TEXT;
eol: EOL;
listOfDouble: DOUBLE (COMMA DOUBLE)*;
COMMAND: PKS;
PKS: 'PKS';
QUERY: '?';
fragment LETTER: [a-zA-Z];
fragment DIGIT: [0-9];
fragment UNDER: [_];
COMMA: ',';
DOUBLE: DIGIT+ (DOT DIGIT*)?;
DOT: '.';
TEXT: LETTER (LETTER | DIGIT | UNDER)*;
EOL: [\n\r];