对多行 ANTLR 重复相同的规则
Repeating same rules for multiple lines ANTLR
我想知道使用 ANTLR 对多行应用解析规则的正确方法是什么。我正在使用以下适用于单行语句的规则。我想在接下来的几行中重复这一点:
grammar Condition;
/* Parser Rules */
condition : (expr+)? EOF;
expr
: expr And expr # andExpr
| expr Or expr # orExpr
| LPar expr RPar # parExpr
| prop MIN Numerical expr # eqExpr
| prop some expr # someExpr
| prop only expr # onlyExpr
| prop value dataValue # valueExpr
| id # idExpr
| not id # idExpr
;
id : Identifier;
prop:Identifier;
dataValue:Identifier;
/* Lexical Tokens */
And : 'AND';
Or : 'OR';
LPar : '(';
RPar : ')';
Equals : '=';
some : 'some';
only : 'only';
MIN : 'MIN';
value:'value';
not:'not';
NEWLINE: ('\n') { skip(); };
Numerical : [1-9] [0-9]*;
Data
: [true]
| [false]
| [A]
| [B]
| [C]
| [D]
;
// Using generic identifier tokens so that better warnings can be given in later passes.
Identifier : [a-zA-Z_] [a-zA-Z0-9_]*;
// Skip parsing of whitespace but save on hidden channel to enable retrieval of original string.
WhiteSpace : [ \t\r\n]+ -> channel(HIDDEN);
// Invalid character rule is used so that the lexer pass never fails.
InvalidChar : .;
上面的语法在测试时给出了正确的结果,但是当我尝试使用访问者时它消耗了每个标记,它抛出了以下错误:
line 2:0 extraneous input 'SafetyGoal' expecting {, 'AND', 'OR'}
有什么建议吗?
编辑
下面是我用来读取输入文件和调用访问者代码的代码:
Stream<String> stream = Files.lines( Paths.get("C:\test\RulesTest.txt"), StandardCharsets.UTF_8);
stream.forEach(s -> contentBuilder.append(s).append("\n"));
String input=contentBuilder.toString();
InputStream inStream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
org.antlr.v4.runtime.ANTLRInputStream in=new org.antlr.v4.runtime.ANTLRInputStream(inStream);
System.out.println("These are the lines:"+contentBuilder);
ConditionLexer lexer=new ConditionLexer(in);
org.antlr.v4.runtime.CommonTokenStream tokens= new org.antlr.v4.runtime.CommonTokenStream(lexer);
ConditionParser parser=new ConditionParser(tokens);
ParseTree tree=parser.expr();
MyVisitor vis=new MyVisitor();
vis.visit(tree);
MyVisitor
基本上包含与 ANTLR 生成的代码相同的代码,我在其中存储解析结果。
您的 Data
规则是错误的:[true]
匹配单个字符(t
、r
、u
或 e
)。改为这样做:
Data
: 'true'
| 'false'
| [A]
| [B]
| [C]
| [D]
;
并且 testResult value true
与您的备选方案 prop value dataValue
不匹配,因为 dataValue
看起来像这样:
dataValue : Identifier;
它应该看起来像这样(我猜):
dataValue : Identifier | Data;
当我如上所述更改您的语法并解析输入时:
(FSR AND testedBy some (testResult value true))
SafetyGoal AND (fulfills some (not NR) OR fulfilledBy some NR)
我得到以下解析树:
ParseTree tree=parser.expr();
您正在调用 expr
规则,它只匹配一个表达式。您的 condition
规则是匹配多个表达式的规则,因此您应该改为调用该规则。
我想知道使用 ANTLR 对多行应用解析规则的正确方法是什么。我正在使用以下适用于单行语句的规则。我想在接下来的几行中重复这一点:
grammar Condition;
/* Parser Rules */
condition : (expr+)? EOF;
expr
: expr And expr # andExpr
| expr Or expr # orExpr
| LPar expr RPar # parExpr
| prop MIN Numerical expr # eqExpr
| prop some expr # someExpr
| prop only expr # onlyExpr
| prop value dataValue # valueExpr
| id # idExpr
| not id # idExpr
;
id : Identifier;
prop:Identifier;
dataValue:Identifier;
/* Lexical Tokens */
And : 'AND';
Or : 'OR';
LPar : '(';
RPar : ')';
Equals : '=';
some : 'some';
only : 'only';
MIN : 'MIN';
value:'value';
not:'not';
NEWLINE: ('\n') { skip(); };
Numerical : [1-9] [0-9]*;
Data
: [true]
| [false]
| [A]
| [B]
| [C]
| [D]
;
// Using generic identifier tokens so that better warnings can be given in later passes.
Identifier : [a-zA-Z_] [a-zA-Z0-9_]*;
// Skip parsing of whitespace but save on hidden channel to enable retrieval of original string.
WhiteSpace : [ \t\r\n]+ -> channel(HIDDEN);
// Invalid character rule is used so that the lexer pass never fails.
InvalidChar : .;
上面的语法在测试时给出了正确的结果,但是当我尝试使用访问者时它消耗了每个标记,它抛出了以下错误:
line 2:0 extraneous input 'SafetyGoal' expecting {, 'AND', 'OR'}
有什么建议吗?
编辑 下面是我用来读取输入文件和调用访问者代码的代码:
Stream<String> stream = Files.lines( Paths.get("C:\test\RulesTest.txt"), StandardCharsets.UTF_8);
stream.forEach(s -> contentBuilder.append(s).append("\n"));
String input=contentBuilder.toString();
InputStream inStream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
org.antlr.v4.runtime.ANTLRInputStream in=new org.antlr.v4.runtime.ANTLRInputStream(inStream);
System.out.println("These are the lines:"+contentBuilder);
ConditionLexer lexer=new ConditionLexer(in);
org.antlr.v4.runtime.CommonTokenStream tokens= new org.antlr.v4.runtime.CommonTokenStream(lexer);
ConditionParser parser=new ConditionParser(tokens);
ParseTree tree=parser.expr();
MyVisitor vis=new MyVisitor();
vis.visit(tree);
MyVisitor
基本上包含与 ANTLR 生成的代码相同的代码,我在其中存储解析结果。
您的 Data
规则是错误的:[true]
匹配单个字符(t
、r
、u
或 e
)。改为这样做:
Data
: 'true'
| 'false'
| [A]
| [B]
| [C]
| [D]
;
并且 testResult value true
与您的备选方案 prop value dataValue
不匹配,因为 dataValue
看起来像这样:
dataValue : Identifier;
它应该看起来像这样(我猜):
dataValue : Identifier | Data;
当我如上所述更改您的语法并解析输入时:
(FSR AND testedBy some (testResult value true))
SafetyGoal AND (fulfills some (not NR) OR fulfilledBy some NR)
我得到以下解析树:
ParseTree tree=parser.expr();
您正在调用 expr
规则,它只匹配一个表达式。您的 condition
规则是匹配多个表达式的规则,因此您应该改为调用该规则。