2011-01-10 15 views
1

ANTLRパーサーと論理式用の木を構築するための以下の文法を書いています。誰かが助けることができる場合:ANTLR:厳密に1つの文字と複数の文字のトークンを1つだけ受け入れるレクサールール

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; 
        } 
        ; 
    

    私は上記の文法で抱えている問題は、これらのです

  1. AntlrFormulaLexerのJavaコードのIMPLICATIONとBICONDITIONALトークンは、それぞれの最初の文字(つまり、 ' - 'と '<')を使用して、文法で指定されているように、文字列全体ではなくトークンに一致させます。

  2. AntlrFormulaParserのJavaコードをテストするとき、 "〜ab"などの文字列を渡すと "(〜a)"というツリーが返されます(文字列 "ab &c" )、原子が上記の文法に従って1文字しか持てないので、実際にはエラー/例外が返されるべきです。これらのサンプル文字列では、エラー/例外は一切発生しません。

誰かが私がこれらの問題を解決する手助けをすることができたら本当に感謝します。ありがとう:)

答えて

1

私のように以下の定義を変更します

IMPLICATION: ('\u2192' | '->'); 
BICONDITIONAL: ('\u2194' | '<->'); 

ノート - ' - >' 対 ">"

とエラーの問題を解決するために:

formula 
    : (
     atom 
     | LEFT_PAREN! biconexpr RIGHT_PAREN! 
    ) EOF 
    ; 

ここから: http://www.antlr.org/wiki/pages/viewpage.action?pageId=4554943

コンパイルする固定文法ANTLR 3.3に対して(AntlrFormula.gとして保存):あなたは完全なファイルを一致させるために、プログラムのルールに一致するようにしようとする必要がありますhttp://www.antlr.org/download/antlr-3.3-complete.jar

grammar AntlrFormula; 

options { 
    output = AST; 
} 


program : formula ; 

formula : atom | LEFT_PAREN! biconexpr RIGHT_PAREN! ; 

biconexpr : impexpr (BICONDITIONAL^ impexpr)*; 

impexpr : orexpr (IMPLICATION^ orexpr)*; 

orexpr : andexpr (DISJUNCTION^ andexpr)*; 

andexpr : notexpr (CONJUNCTION^ notexpr)*; 

notexpr : (NEGATION^)? formula; 


atom 
    : CHAR 
    | TRUTH 
    | FALSITY 
    ; 


// 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') { $channel = HIDDEN; }; 

リンクは3.3バイナリをANTLRします。 エラー:トークンストリームの読み取りエラー文法(S): Formula.g:41:28:私は上記の定義と、このエラーが出る

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) { 
     AntlrFormulaLexer lexer = new AntlrFormulaLexer(new ANTLRStringStream("(~ab)")); 
     AntlrFormulaParser p = new AntlrFormulaParser(new CommonTokenStream(lexer)); 

     try { 
      p.program(); 
      if (p.failed() || p.getNumberOfSyntaxErrors() != 0) { 
       System.out.println("failed"); 
      } 
     } catch (RecognitionException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

:期待 ''」このクラスでテスト可能

、 '' 'を見つけました。 TokenStreamException:' ''が見つかりました '>' 私はあなたの定義を最初に試したと思いますが、エラーを受けて二重引用符に切り替えることにしました。 – ChocolateBear

+0

奇妙な..彼らのサンプルでは、​​これを許可しています:ASSERT: 'assert';自分のサイトからjava.gの文法を見てください。 –

+0

はクロージャ文法と同じです。 https://github.com/laurentpetit/ccw/blob/master/clojure-antlr-grammar/src/Clojure.g。どのようなantlrバージョンを使用していますか? –

関連する問題