我在Coco / R中有一个悬而未决的问题。我尝试理解Coco/R User Manual并问谷歌,但我无法自己解决问题。
我将我的问题简化为以下Coco / R语法(保存在new4.atg
中):
COMPILER Expr
CHARACTERS
digit = '0'..'9'.
letter = 'A'..'Z'.
TOKENS
number = digit { digit }.
name = letter { digit | letter }.
PRODUCTIONS
Expr = Test | Id Test.
Test = Test2.
Test2=Id | "(" Test ")".
Id=IdName|IdNumber.
IdName = name.
IdNumber = number.
END Expr.
当我想用coco.bat
构建编译器时,我得到了这个答案:
Coco/R (Dec 22, 2014)
checking
new 4.atg(15,1): LL1 warning in Expr: number is start of several alternatives
new 4.atg(15,1): LL1 warning in Expr: name is start of several alternatives
parser + scanner generated
0 errors detected
在best result in Google中,我已经读过我可以声明IF(isXXXFollowYYY())
语句,但我不知道如何以及它是否是最佳解决方案。
(在我的示例中:Expr = Test | If(isTestFollowID)Id Test
。但isTestFollowID
在哪里宣布?)
当我开始coco.bat
时,我希望不会收到任何警告。
答案 0 :(得分:0)
你的语法含糊不清。
从Expr
开始,在看到Id
令牌后,解析器可以转到
Expr -> Test -> Test2 -> Id
或
Expr -> Id
LL(1)解析器不知道要采用哪条路径。
通过将Id
拉入Expr
制作中的导入可选组件,可以解决当前问题:
而不是
Expr = Test | Id Test.
你可以做到
Expr = [Id] Test .
然而,Test
制作也可以在开始时匹配Id
,因此看起来需要进一步的重构才能使语法LL(1)。