2016-04-21 73 views
0

我似乎无法弄清楚为什么这个语法不能编译。它编译罚款,直到我修改行145我该如何重构这个ANTLR4语法,以便它不是相互左递归?

(Identifier '.')* functionCall 

(primary '.')? functionCall 

我一直在试图找出如何解决这个问题一段时间,但我似乎无法能够。这里的错误:

The following sets of rules are mutually left-recursive [primary]

grammar Tadpole; 

@header 
{package net.tadpole.compiler.parser;} 

file 
    : fileContents* 
    ; 

fileContents 
    : structDec 
    | functionDec 
    | statement 
    | importDec 
    ; 

importDec 
    : 'import' Identifier ';' 
    ; 

literal 
    : IntegerLiteral 
    | FloatingPointLiteral 
    | BooleanLiteral 
    | CharacterLiteral 
    | StringLiteral 
    | NoneLiteral 
    | arrayLiteral 
    ; 

arrayLiteral 
    : '[' expressionList? ']' 
    ; 

expressionList 
    : expression (',' expression)* 
    ; 

expression 
    : primary 
    | unaryExpression 
    | <assoc=right> expression binaryOpPrec0 expression 
    | <assoc=left> expression binaryOpPrec1 expression 
    | <assoc=left> expression binaryOpPrec2 expression 
    | <assoc=left> expression binaryOpPrec3 expression 
    | <assoc=left> expression binaryOpPrec4 expression 
    | <assoc=left> expression binaryOpPrec5 expression 
    | <assoc=left> expression binaryOpPrec6 expression 
    | <assoc=left> expression binaryOpPrec7 expression 
    | <assoc=left> expression binaryOpPrec8 expression 
    | <assoc=left> expression binaryOpPrec9 expression 
    | <assoc=left> expression binaryOpPrec10 expression 
    | <assoc=right> expression binaryOpPrec11 expression 
    ; 

unaryExpression 
    : unaryOp expression 
    | prefixPostfixOp primary 
    | primary prefixPostfixOp 
    ; 

unaryOp 
    : '+' 
    | '-' 
    | '!' 
    | '~' 
    ; 

prefixPostfixOp 
    : '++' 
    | '--' 
    ; 

binaryOpPrec0 
    : '**' 
    ; 
binaryOpPrec1 
    : '*' 
    | '/' 
    | '%' 
    ; 
binaryOpPrec2 
    : '+' 
    | '-' 
    ; 
binaryOpPrec3 
    : '>>' 
    | '>>>' 
    | '<<' 
    ; 
binaryOpPrec4 
    : '<' 
    | '>' 
    | '<=' 
    | '>=' 
    | 'is' 
    ; 
binaryOpPrec5 
    : '==' 
    | '!=' 
    ; 
binaryOpPrec6 
    : '&' 
    ; 
binaryOpPrec7 
    : '^' 
    ; 
binaryOpPrec8 
    : '|' 
    ; 
binaryOpPrec9 
    : '&&' 
    ; 
binaryOpPrec10 
    : '||' 
    ; 
binaryOpPrec11 
    : '=' 
    | '**=' 
    | '*=' 
    | '/=' 
    | '%=' 
    | '+=' 
    | '-=' 
    | '&=' 
    | '|=' 
    | '^=' 
    | '>>=' 
    | '>>>=' 
    | '<<=' 
    | '<-' 
    ; 

primary 
    : literal 
    | fieldName 
    | '(' expression ')' 
    | '(' type ')' (primary | unaryExpression) 
    | 'new' objType '(' expressionList? ')' 
    | primary '.' fieldName 
    | primary dimension 
    | (primary '.')? functionCall 
    ; 

functionCall 
    : functionName '(' expressionList? ')' 
    ; 

functionName 
    : Identifier 
    ; 

dimension 
    : '[' expression ']' 
    ; 

statement 
    : '{' statement* '}' 
    | expression ';' 
    | 'recall' ';' 
    | 'return' expression? ';' 
    | variableDec 
    | 'if' '(' expression ')' statement ('else' statement)? 
    | 'while' '(' expression ')' statement 
    | 'do' expression 'while' '(' expression ')' ';' 
    | 'do' '{' statement* '}' 'while' '(' expression ')' ';' 
    ; 

structDec 
    : 'struct' structName ('(' parameterList ')')? '{' variableDec* functionDec* '}' 
    ; 

structName 
    : Identifier 
    ; 

fieldName 
    : Identifier 
    ; 

variableDec 
    : type fieldName ('=' expression)? ';' 
    ; 

type 
    : primitiveType ('[' ']')* 
    | objType ('[' ']')* 
    ; 

primitiveType 
    : 'byte' 
    | 'short' 
    | 'int' 
    | 'long' 
    | 'char' 
    | 'boolean' 
    | 'float' 
    | 'double' 
    ; 

objType 
    : (Identifier '.')? structName 
    ; 

functionDec 
    : 'def' functionName '(' parameterList? ')' ':' type '->' functionBody 
    ; 

functionBody 
    : statement 
    ; 

parameterList 
    : parameter (',' parameter)* 
    ; 

parameter 
    : type fieldName 
    ; 

IntegerLiteral 
    : DecimalIntegerLiteral 
    | HexIntegerLiteral 
    | OctalIntegerLiteral 
    | BinaryIntegerLiteral 
    ; 

fragment 
DecimalIntegerLiteral 
    : DecimalNumeral IntegerSuffix? 
    ; 

fragment 
HexIntegerLiteral 
    : HexNumeral IntegerSuffix? 
    ; 

fragment 
OctalIntegerLiteral 
    : OctalNumeral IntegerSuffix? 
    ; 

fragment 
BinaryIntegerLiteral 
    : BinaryNumeral IntegerSuffix? 
    ; 

fragment 
IntegerSuffix 
    : [lL] 
    ; 

fragment 
DecimalNumeral 
    : Digit (Digits? | Underscores Digits) 
    ; 

fragment 
Digits 
    : Digit (DigitsAndUnderscores? Digit)? 
    ; 

fragment 
Digit 
    : [0-9] 
    ; 

fragment 
DigitsAndUnderscores 
    : DigitOrUnderscore+ 
    ; 

fragment 
DigitOrUnderscore 
    : Digit 
    | '_' 
    ; 

fragment 
Underscores 
    : '_'+ 
    ; 

fragment 
HexNumeral 
    : '0' [xX] HexDigits 
    ; 

fragment 
HexDigits 
    : HexDigit (HexDigitsAndUnderscores? HexDigit)? 
    ; 

fragment 
HexDigit 
    : [0-9a-fA-F] 
    ; 

fragment 
HexDigitsAndUnderscores 
    : HexDigitOrUnderscore+ 
    ; 

fragment 
HexDigitOrUnderscore 
    : HexDigit 
    | '_' 
    ; 

fragment 
OctalNumeral 
    : '0' [oO] Underscores? OctalDigits 
    ; 

fragment 
OctalDigits 
    : OctalDigit (OctalDigitsAndUnderscores? OctalDigit)? 
    ; 

fragment 
OctalDigit 
    : [0-7] 
    ; 

fragment 
OctalDigitsAndUnderscores 
    : OctalDigitOrUnderscore+ 
    ; 

fragment 
OctalDigitOrUnderscore 
    : OctalDigit 
    | '_' 
    ; 

fragment 
BinaryNumeral 
    : '0' [bB] BinaryDigits 
    ; 

fragment 
BinaryDigits 
    : BinaryDigit (BinaryDigitsAndUnderscores? BinaryDigit)? 
    ; 

fragment 
BinaryDigit 
    : [01] 
    ; 

fragment 
BinaryDigitsAndUnderscores 
    : BinaryDigitOrUnderscore+ 
    ; 

fragment 
BinaryDigitOrUnderscore 
    : BinaryDigit 
    | '_' 
    ; 

// §3.10.2 Floating-Point Literals 

FloatingPointLiteral 
    : DecimalFloatingPointLiteral FloatingPointSuffix? 
    | HexadecimalFloatingPointLiteral FloatingPointSuffix? 
    ; 

fragment 
FloatingPointSuffix 
    : [fFdD] 
    ; 

fragment 
DecimalFloatingPointLiteral 
    : Digits '.' Digits? ExponentPart? 
    | '.' Digits ExponentPart? 
    | Digits ExponentPart 
    | Digits 
    ; 

fragment 
ExponentPart 
    : ExponentIndicator SignedInteger 
    ; 

fragment 
ExponentIndicator 
    : [eE] 
    ; 

fragment 
SignedInteger 
    : Sign? Digits 
    ; 

fragment 
Sign 
    : [+-] 
    ; 

fragment 
HexadecimalFloatingPointLiteral 
    : HexSignificand BinaryExponent 
    ; 

fragment 
HexSignificand 
    : HexNumeral '.'? 
    | '0' [xX] HexDigits? '.' HexDigits 
    ; 

fragment 
BinaryExponent 
    : BinaryExponentIndicator SignedInteger 
    ; 

fragment 
BinaryExponentIndicator 
    : [pP] 
    ; 

BooleanLiteral 
    : 'true' 
    | 'false' 
    ; 

CharacterLiteral 
    : '\'' SingleCharacter '\'' 
    | '\'' EscapeSequence '\'' 
    ; 

fragment 
SingleCharacter 
    : ~['\\] 
    ; 

StringLiteral 
    : '"' StringCharacters? '"' 
    ; 

fragment 
StringCharacters 
    : StringCharacter+ 
    ; 

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

fragment 
EscapeSequence 
    : '\\' [btnfr"'\\] 
    | OctalEscape 
    | UnicodeEscape 
    ; 

fragment 
OctalEscape 
    : '\\' OctalDigit 
    | '\\' OctalDigit OctalDigit 
    | '\\' ZeroToThree OctalDigit OctalDigit 
    ; 

fragment 
ZeroToThree 
    : [0-3] 
    ; 

fragment 
UnicodeEscape 
    : '\\' 'u' HexDigit HexDigit HexDigit HexDigit 
    ; 

NoneLiteral 
    : 'nil' 
    ; 

Identifier 
    : IdentifierStartChar IdentifierChar* 
    ; 

fragment 
IdentifierStartChar 
    : [a-zA-Z$_] // these are the "java letters" below 0xFF 
    | // covers all characters above 0xFF which are not a surrogate 
     ~[\u0000-\u00FF\uD800-\uDBFF] 
     {Character.isJavaIdentifierStart(_input.LA(-1))}? 
    | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 
     [\uD800-\uDBFF] [\uDC00-\uDFFF] 
     {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? 
    ; 

fragment 
IdentifierChar 
    : [a-zA-Z0-9$_] // these are the "java letters or digits" below 0xFF 
    | // covers all characters above 0xFF which are not a surrogate 
     ~[\u0000-\u00FF\uD800-\uDBFF] 
     {Character.isJavaIdentifierPart(_input.LA(-1))}? 
    | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 
     [\uD800-\uDBFF] [\uDC00-\uDFFF] 
     {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? 
    ; 

WS : [ \t\r\n\u000C]+ -> skip 
    ; 

LINE_COMMENT 
    : '#' ~[\r\n]* -> skip 
    ; 
+1

你能发表产生这个错误的完整文法吗? –

+0

@BartKiers完成 – EnderShadow

+0

不,它没有“完成”你发布了一个LINK到非现场资源,你没有发布语法。 –

回答

1

左递归调用需要是第一,所以没有括号前,可以进行放置。

你可以把它改写这样的:

primary 
    : literal 
    | fieldName 
    | '(' expression ')' 
    | '(' type ')' (primary | unaryExpression) 
    | 'new' objType '(' expressionList? ')' 
    | primary '.' fieldName 
    | primary dimension 
    | primary '.' functionCall 
    | functionCall 
    ; 

这相当于。