2012-03-01 43 views
1

我正在使用ANTLR創建和/或解析器+評估器。表達式將會有這樣的格式:antlr解析器和/或邏輯 - 如何獲得邏輯運算符之間的表達式?

  • x eq 1 && y eq 10
  • (x lt 10 && x gt 1) OR x eq -1

我正在讀的邏輯表達式這個帖子在ANTLR Looking for advice on project. Parsing logical expression,我發現語法貼有一個良好的開端:

grammar Logic; 

parse 
    : expression EOF 
    ; 

expression 
    : implication 
    ; 

implication 
    : or ('->' or)* 
    ; 

or 
    : and ('&&' and)* 
    ; 

and 
    : not ('||' not)* 
    ; 

not 
    : '~' atom 
    | atom 
    ; 

atom 
    : ID 
    | '(' expression ')' 
    ; 

ID : ('a'..'z' | 'A'..'Z')+; 
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;}; 

但是,雖然從解析器中獲取樹對於變量只是表達式一個字符(即,"(A || B) AND C",我很難適應這種情況(例如"x eq 1 && y eq 10"我期望一個"AND"父母和兩個孩子,"x eq 1""y eq 10",請參閱下面的測試用例)。我想這與"ID"有關。正確的語法是什麼?

+0

在這裏發佈,以及:HTTP://antlr.markmail。org/message/bk6kutcu56vuglgl – 2012-03-01 18:52:09

回答

2

對於那些有興趣,我改變了我的語法文件的一些改進(參見下文)

電流限制:

  • 只適用於& &/||,而不是AND/OR(不是很有問題的)

  • 你不能有括號和& &/||之間的空間(我解決了這個問題,在輸入詞法分析器之前,用源代碼字符串中的「)」替換「(」,「)」和「)」,

    語法邏輯;

    options { 
        output = AST; 
    } 
    
    tokens { 
        AND = '&&'; 
        OR = '||'; 
        NOT = '~'; 
    } 
    
    // parser/production rules start with a lower case letter 
    parse 
        : expression EOF! // omit the EOF token 
        ; 
    
    expression 
        : or 
        ; 
    
    or 
        : and (OR^ and)* // make `||` the root 
        ; 
    
    and 
        : not (AND^ not)*  // make `&&` the root 
        ; 
    
    not 
        : NOT^ atom // make `~` the root 
        | atom 
        ; 
    
    atom 
        : ID 
        | '('! expression ')'! // omit both `(` and `)` 
        ; 
    
    // lexer/terminal rules start with an upper case letter 
    ID 
        : 
        (
        'a'..'z' 
        | 'A'..'Z' 
        | '0'..'9' | ' ' 
        | SYMBOL 
    )+ 
        ; 
    
    SYMBOL 
        : 
        ('+'|'-'|'*'|'/'|'_') 
    ; 
    
0
ID : ('a'..'z' | 'A'..'Z')+; 

指出標識符是一個或多個字母的序列,但不允許任何數字。嘗試

ID : ('a'..'z' | 'A'..'Z' | '0'..'9')+; 

這將允許例如, abc,123,12abab12。如果你不想要後者,你必須重新調整規則(留作挑戰...)

爲了接受任意多個標識符,你可以將​​定義爲ID+而不是ID

此外,你可能會需要指定ANDOR->~作爲標記,以便作爲@Bart煮布鍋說,前兩個不會得到列爲ID,所以後兩者將得到認可在所有。

+0

@Aasmund,這並沒有考慮我認爲的兩件事:一個令牌可以有空格(「綠色neq綠色」應該是一個令牌)的事實。此外,使用AND/OR而不是&&/||,不應該在ID中說出類似〜和&&〜或(或〜「AND」,〜「OR」)的內容嗎? – mmalmeida 2012-03-01 09:39:08

+0

@wild_oscar:我沒有明白。看到我更新的答案。 – 2012-03-01 11:58:29

+0

@AasmundEldhuset:如果您將原子更改爲ID +,但不向ID添加「|''」,是不是說您期望IDID ... ID,即1eq1(不含空格)?該語法標記1 eq 1 || B轉換成父母||和4個孩子(1,eq,1,B),而不是2個孩子(1 eq 1,B)。 – mmalmeida 2012-03-01 14:30:21