簡體   English   中英

Antlr4語法問題(不完全解析)

[英]Antlr4 Grammar issue (not entirely parsing)

我是ANTLR的新手,正在嘗試使此語法有效:

grammar TemplateGrammar;

//Parser Rules 

start
    : block
    | statement
    | expression
    | parExpression
    | primary
    ;

block
    : LBRACE statement* RBRACE
    ;

statement
    : block
    | IF parExpression statement (ELSE statement)?
    | expression
    ;

parExpression
    : LPAREN expression RPAREN
    ;

expression
    : primary #PRIMARY
    | number op=('*'|'/') number            #MULDIV
    | number op=('+'|'-') number            #ADDSUB
    | number op=('>='|'<='|'>'|'<') number  #GRLWOREQUALS
    | expression op=('='|'!=') expression   #EQDIFF
    ;

primary
    :   parExpression
    |   literal
    ;

literal
    :   number  #NumberLiteral
    |   string  #StringLiteral
    |   columnName #ColumnNameLiteral
    ;

number
    :   DecimalIntegerLiteral       #DecimalIntegerLiteral
    |   DecimalFloatingPointLiteral #FloatLiteral
    ;

string
    :   '"' StringChars? '"'
    ;

columnName
    :   '[' StringChars? ']'
    ;

// Lexer Rules

//Integers
 DecimalIntegerLiteral
    :   DecimalNumeral
    ;

 fragment
 DecimalNumeral
    :   '0'
    |   NonZeroDigit (Digits? | Underscores Digits)
    ;

 fragment
 Digits
    :   Digit (DigitOrUnderscore* Digit)?
    ;

 fragment
 Digit
    :   '0'
    |   NonZeroDigit
    ;

 fragment
 NonZeroDigit
    :   [1-9]
    ;

 fragment
 DigitOrUnderscore
    :   Digit
    |   '_'
    ;

 fragment
 Underscores
    :   '_'+
    ;

//Floating point
DecimalFloatingPointLiteral
    :   Digits '.' Digits? ExponentPart?
    |   '.' Digits ExponentPart?
    |   Digits ExponentPart
    |   Digits
    ;

fragment
ExponentPart
    :   ExponentIndicator SignedInteger
    ;

fragment
ExponentIndicator
    :   [eE]
    ;

fragment
SignedInteger
    :   Sign? Digits
    ;

fragment
Sign
    :   [+-]
    ;

//Strings

StringChars
    :   StringChar+
    ;

fragment
StringChar
    :   ~["\\]
    |   EscapeSequence
    ;

fragment
EscapeSequence
    :   '\\' [btnfr"'\\]
    ;

//Separators
LPAREN          : '(';
RPAREN          : ')';
LBRACE          : '{';
RBRACE          : '}';
LBRACK          : '[';
RBRACK          : ']';
COMMA           : ',';
DOT             : '.';

//Keywords
IF              : 'IF';
ELSE            : 'ELSE';
THEN            : 'THEN';

//Operators
PLUS            : '+';
MINUS           : '-';
MULTIPLY        : '*';
DIVIDE          : '/';
EQUALS          : '=';
DIFFERENT       : '!=';
GRTHAN          : '>';
GROREQUALS      : '>=';
LWTHAN          : '<';
LWOREQUALS      : '<=';
AND             : '&';
OR              : '|';

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ -> skip ;


當我在輸入中輸入"Test"時,它正在工作並返回字符串"Test"

這是我在輸入中輸入"Test"時在IParseTree得到的IParseTree

“(開始(聲明(表達式(主要(文字(字符串\\“測試\\”)))))))”


但是,當我放入[Test] (與"Test"幾乎一樣,但用大括號而不是引號)時,解析器無法識別標記...

這是我放[Tree]時得到的IParseTree

“(開始[測試])”


同樣的,數字,它也承認孤獨的數字,如112312.5 ,等等,但沒有這樣的表達式1+2 ...

您是否知道解析器為什么不識別columnNames規則,但與string規則配合使用呢?

可能是因為您的目的定義了不正確的“ StringChar”? 它不處理“]”

也許您想將StringChar定義為:

fragment
StringChar
:   ~["\\\]]
|   EscapeSequence
;

如果這是我的語法,我將為引用的字符串定義一個QuotedStringChar,並將BracketStringChar定義為〜[\\] \\\\]以用於您的括號列名稱。

歡迎您在詞匯層調試語法,並為不同類型的字符串定義不同類型的“引號”。 這很普遍。 (您應該看到Ruby,您可以在其中以字符串開頭ick定義字符串引號。)

我最終通過以下方法使它起作用:

QuotedStringChars
    :   '"' ~[\"]+ '"'
    ;

BracketStringChars
    :   '[' ~[\]]+ ']'
    ;

在引號或方括號之間使用任何字符。 然后 :

primary
    :   literal #PrimLiteral
    |   number  #PrimNumber
    ;

literal
    :   QuotedStringChars   #OneString
    |   BracketStringChars  #ColumnName
    |   number              #NUMBER
    ;

number
    :   DecimalIntegerLiteral       #DecimalIntegerLiteral
    |   DecimalFloatingPointLiteral #FloatLiteral
    ;

literal規則有助於區分帶引號的字符串,方括號和數字。

primary規則和literal規則中number是重復的,因為我需要為每個應用程序使用不同的行為。

我用Ira Baxter的好建議來解決這個問題:)

希望這可以幫助其他像我這樣的ANTLR新手獲得更好的理解:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM