2013-06-11 3 views
1

Я пытаюсь создать грамматику в ANTLR, которая оценивает формулы логики высказываний. Поэтому для ввода (1 & 0) | 1 он должен вернуть true.ANTLR Propositional Logic Evaluator

Я построил следующее:

code returns[boolean value] 
    : formula EOF {$value = $formula.value;} 
    ; 

formula returns [boolean value] 
    : equiv {$value = $equiv.value;} 
    ; 

equiv returns [boolean value] 
    : a=implies {$value = $a.value;} 
    ('#' b=implies {$value = $value == $b.value;} 
)* 
    ; 

implies returns [boolean value] 
    : a=or {$value = $a.value;} 
    ('>' b=or {$value = !$value || $b.value;} 
)* 
    ; 

or returns [boolean value] 
    : a=and {$value = $a.value;} 
    ('|' b=and {$value ||= $b.value;} 
)* 
    ; 

and returns [boolean value] 
    : a=term {$value = $a.value;} 
    ('&' b=term {$value &&= $b.value;} 
)* 
    ; 

term returns [boolean value] 
    : '(' formula ')' {$value = $formula.value;} 
    | '0' {$value = false;} 
    | '1' {$value = true;} 
    | '¬' term {$value = !$term.value;} 
    ; 

WHITESPACE: (' '|'\t'|'\r'|'\f'|'\n')+{$channel = HIDDEN;} ; 

Однако я получаю ошибку java.lang.NoSuchFieldError: offendingToken. Есть ли в любом случае, чтобы узнать, где ошибка или как ее исправить?

+1

Как эксперт, не являющийся ANTLR, я отлаживаю эти проблемы, просматривая сгенерированный код Java. Трассировка стека должна содержать номера строк, а сгенерированный код будет содержать комментарии, указывающие, какая часть этого правила представлена. –

ответ

1

Есть 3 вопроса:

  • {$value ||= $b.value;} должен быть {$value = $value || $b.value;}
  • {$value &&= $b.value;} должен быть {$value = $value && $b.value;}
  • метка $term в четвертой альтернативе term правила неоднозначно: это может относиться к самому правилу , или term, а затем '¬'


Т.е., следующее:

term returns [boolean value] 
    : ... 
    | '¬' term {$value = !$term.value;} 
    ; 

должно быть:

term returns [boolean value] 
    : ... 
    | '¬' t=term {$value = !$t.value;} 
    ; 

Сделав эти изменения, следующий тест класса:

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    String source = "(1 & 0) | 1"; 
    TestLexer lexer = new TestLexer(new ANTLRStringStream(source)); 
    TestParser parser = new TestParser(new CommonTokenStream(lexer)); 
    System.out.println(source + " = " + parser.code()); 
    } 
} 

производит желаемый результат:

java -cp antlr-3.3.jar org.antlr.Tool Test.g 
javac -cp antlr-3.3.jar *.java 
java -cp .:antlr-3.3.jar Main 

(1 & 0) | 1 = true 
+0

Большое спасибо за вашу помощь! Я пытался следить за одной из ваших ранних должностей по оценке операций +, -, /, *, но не мог видеть, где я здесь ошибся. Я действительно думал, что || = и && = будет разрешено. Еще раз спасибо! – charlie123

+0

Добро пожаловать @ charlie123. –