論理式のツリーを構築するためのANTLRパーサーとレクサーの以下の文法を書きました。誰かが助けてくれるかどうかいくつか質問がありました。
class AntlrFormulaParser extends Parser;
options {
buildAST = true;
}
biconexpr : impexpr (BICONDITIONAL^ impexpr)*;
impexpr : orexpr (IMPLICATION^ orexpr)*;
orexpr : andexpr (DISJUNCTION^ andexpr)*;
andexpr : notexpr (CONJUNCTION^ notexpr)*;
notexpr : (NEGATION^)? formula;
formula
: atom
| LEFT_PAREN! biconexpr RIGHT_PAREN!
;
atom
: CHAR
| TRUTH
| FALSITY
;
class AntlrFormulaLexer extends Lexer;
// Atoms
CHAR: 'a'..'z';
TRUTH: ('\u22A4' | 'T');
FALSITY: ('\u22A5' | 'F');
// Grouping
LEFT_PAREN: '(';
RIGHT_PAREN: ')';
NEGATION: ('\u00AC' | '~' | '!');
CONJUNCTION: ('\u2227' | '&' | '^');
DISJUNCTION: ('\u2228' | '|' | 'V');
IMPLICATION: ('\u2192' | "->");
BICONDITIONAL: ('\u2194' | "<->");
WHITESPACE : (' ' | '\t' | '\r' | '\n') { $setType(Token.SKIP); };
ツリーの文法:
tree grammar AntlrFormulaTreeParser;
options {
tokenVocab=AntlrFormula;
ASTLabelType=CommonTree;
}
expr returns [Formula f]
: ^(BICONDITIONAL f1=expr f2=expr) {
$f = new Biconditional(f1, f2);
}
| ^(IMPLICATION f1=expr f2=expr) {
$f = new Implication(f1, f2);
}
| ^(DISJUNCTION f1=expr f2=expr) {
$f = new Disjunction(f1, f2);
}
| ^(CONJUNCTION f1=expr f2=expr) {
$f = new Conjunction(f1, f2);
}
| ^(NEGATION f1=expr) {
$f = new Negation(f1);
}
| CHAR {
$f = new Atom($CHAR.getText());
}
| TRUTH {
$f = Atom.TRUTH;
}
| FALSITY {
$f = Atom.FALSITY;
}
;
上記の文法で私が抱えている問題は次のとおりです。
AntlrFormulaLexerのJavaコードのトークンIMPLICATIONおよびBICONDITIONALは、文法で指定されているように、文字列全体ではなく、それぞれの最初の文字(つまり、「-」および「<」)がトークンと一致するかどうかをチェックしているようです。
AntlrFormulaParserのJavaコードをテストするときに、「〜ab」などの文字列を渡すと、「(〜a)」のツリーが返されます(文字列「ab&c」は「a」だけを返します)。上記の文法によれば、アトムは1文字しか持てないため、エラー/例外を返します。これらのサンプル文字列では、エラーや例外はまったく発生しません。
誰かが私がこれらのいくつかの問題を解決するのを手伝ってくれるなら、私は本当に感謝しています。ありがとうございました :)