我怎样才能重构这个ANTLR4语法,以便它不会相互递归递归?

时间:2016-04-21 13:49:50

标签: antlr4

我似乎无法弄清楚为什么这个语法不会编译。它编译得很好,直到我从

修改了第145行
(Identifier '.')* functionCall

(primary '.')? functionCall

我一直试图弄清楚如何解决这个问题一段时间,但我似乎无法做到。这是错误:

  

以下几组规则是相互左递归的[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 :(得分:1)

左递归调用需要是第一个,因此不能在它之前放置括号。

您可以这样重写:

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

等同。