我正在爲Clasp
的輸出寫入解析器ANTLR 4
。典型的輸出是這樣的:使用INT和FLOAT進行意外的ANTLR4優化?
clasp version 3.0.3
Reading from stdin
Solving...
Answer: 1
bird(a) bird(b) bird(c) penguin(d) bird(d)
Optimization: 7 0
Answer: 2
bird(a) bird(b) bird(c) penguin(d) bird(d) flies_abd(b) flies(b)
Optimization: 6 5
Answer: 3
bird(a) bird(b) bird(c) penguin(d) bird(d) flies_abd(c) flies(c)
Optimization: 2 5
Answer: 4
bird(a) bird(b) bird(c) penguin(d) bird(d) flies_abd(a) flies_abd(c) flies(a) flies(c)
Optimization: 1 10
Answer: 5
bird(a) bird(b) bird(c) penguin(d) bird(d) flies_abd(a) flies_abd(b) flies_abd(c) flies(a) flies(b) flies(c)
Optimization: 0 15
OPTIMUM FOUND
Models : 5
Optimum : yes
Optimization : 0 15
Calls : 1
Time : 0.002s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.000s
我必須檢查clasp
是版本3
所以我寫類似以下的語法:
/**
* Define a grammar for Clasp 3's output.
*/
grammar Output;
@header {package ac.bristol.clasp.parser;}
output:
version source solving answer* result separation statistics NEWLINE* EOF;
version: 'clasp version 3.' INT '.' INT NEWLINE;
source: 'Reading from stdin' NEWLINE # sourceSTDIN
| 'Reading from ' path NEWLINE # sourceFile;
path:
DRIVE? folder (BSLASH folder)* filename # pathWindows
| FSLASH? folder (FSLASH folder)* filename # pathNIX;
folder:
LETTER+ # genericFolder
| DOTDOT # parentFolder
| DOT # currentFolder;
solving: 'Solving...' NEWLINE;
filename:
LETTER+ extension?;
extension:
DOT LETTER*;
answer: 'Answer: ' INT NEWLINE //
model? NEWLINE //
'Optimization: ' INT (SPACE INT)* NEWLINE;
model:
fact (SPACE fact)*;
fact:
groundPredicate;
groundTermList:
groundTerm (COMMA groundTerm)*;
groundTerm:
groundCompound | STRING | number | atom; // literal?
groundCompound:
groundPredicate
| groundExpression;
groundPredicate:
IDENTIFIER (LROUND groundTermList RROUND)?;
groundExpression:
groundBits AND groundBits
| groundBits OR groundBits
| groundBits XOR groundBits;
groundBits:
groundCompare GT groundCompare
| groundCompare GE groundCompare
| groundCompare LT groundCompare
| groundCompare LE groundCompare;
groundCompare:
groundItem EQ groundItem
| groundItem NE groundItem;
groundItem:
groundFactor PLUS groundFactor
| groundFactor MINUS groundFactor;
groundFactor:
groundUnary TIMES groundUnary
| groundUnary DIVIDE groundUnary
| groundUnary MOD groundUnary;
groundUnary:
TILDE groundTerm
| MINUS groundTerm;
atom:
IDENTIFIER
| QUOTED;
number:
INT
| FLOAT;
//------------------------------------------------------------------------------
result: 'OPTIMUM FOUND' NEWLINE
| 'SATISFIABLE' NEWLINE
| 'UNKNOWN' NEWLINE;
separation:
NEWLINE;
statistics:
models optimum? optimization calls time cputime;
models: 'Models : ' INT SPACE* NEWLINE;
optimum: ' Optimum : yes' NEWLINE
| ' Optimum : no' NEWLINE;
optimization: 'Optimization : ' INT (SPACE INT)* NEWLINE;
calls: 'Calls : ' INT NEWLINE;
time: 'Time : ' FLOAT 's (Solving: ' FLOAT 's 1st Model: ' FLOAT 's Unsat: ' FLOAT 's)' NEWLINE;
cputime: 'CPU Time : ' FLOAT 's';
//------------------------------------------------------------------------------
AND: '&';
BSLASH: '\\';
COLON: ':';
COMMA: ',';
DIVIDE: '/';
DOT: '.';
DOTDOT: '..';
EQ: '==';
FSLASH: '/';
GE: '>=';
GT: '>';
LE: '<=';
LROUND: '(';
LT: '<';
MINUS: '-';
MOD: '%';
NE: '!=';
OR: '?';
PLUS: '+';
RROUND: ')';
SEMICOLON: ';';
SPACE: ' ';
TILDE: '~';
TIMES: '*';
XOR: '^';
DRIVE: (LOWER | UPPER) COLON BSLASH?;
IDENTIFIER: LOWER FOLLOW*;
INT: DIGIT+;
FLOAT: DIGIT+ DOT DIGIT+;
NEWLINE: '\r'? '\n';
QUOTED: '\'' (~[\'\\] | ESCAPE)+? '\'';
STRING: '"' (~["\\] | ESCAPE)+? '"';
fragment DIGIT: [0] | NONZERO;
fragment ESCAPE: '\\' [btnr"\\] | '\\' [0-3]? [0-7]? [0-7] | '\\' 'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F];
fragment FOLLOW: LOWER | UPPER | DIGIT | UNDERSCORE;
fragment LETTER: LOWER | UPPER | DIGIT | SPACE;
fragment LOWER: [a-z];
fragment NONZERO: [1-9];
fragment UNDERSCORE: [_];
fragment UPPER: [A-Z];
注意,沒有規則skip
一些部分輸入流,因爲我想檢查每一個字符。 另請注意,我有一個終止規則INT
有史以來和FLOAT
,INT
是在FLOAT
之前定義的,FLOAT
s是如在Prolog中定義的。
來解析上述例子中的第一行的規則是以下內容:
version: 'clasp version 3.' INT '.' INT NEWLINE;
,因爲它我要檢查正在使用的clasp
主版本號是3,比我要消耗其餘該行讀取次要版本號,點號,內部版本號和換行符(不帶空格或任何內容)。 不幸的是,我得到以下警告消息,這讓我覺得ANTLR是認識次要版本號,點和內部版本號爲FLOAT
:
line 1:16 mismatched input '0.3' expecting INT
能否請你解釋我是怎麼回事?
我假設我不應該這樣做嗎?
或者是ANTLR
這是應用不需要的優化?
嗨山姆(@ 280Z28),感謝您的幫助的解釋!我的誤解可能是由於我正在考慮將解析器作爲基本的遞歸後裔解析器,並選擇了令牌接受的產品。無論如何,我認爲我會將'INT DOT INT'變成'FLOAT',作爲使警告消失的臨時解決方案(畢竟我沒有在其他地方使用這些數字),但我會研究如何區分語法分析器語法和詞法分析器語法,因爲學習新東西總是一件好事!非常感謝您的幫助! –