我在Coco/R中有一个悬挂问题。我试着理解Coco/R用户手册,我问了谷歌,但我不能自己解决这个问题。
我将问题简化为以下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
在谷歌最好的结果,我已经读到,我可以声明IF(isXXXFollowYYY())
声明,但我不知道如何,如果它是最好的解决方案。(在我的例子中:Expr = Test | If(isTestFollowID)Id Test
。但是在哪里声明isTestFollowID
?)
我想得到没有警告,当我启动coco.bat
.
您的语法有歧义。
从Expr
,在看到Id
标记时,解析器可以转到
Expr -> Test -> Test2 -> Id
或
Expr -> Id
LL(1)解析器不知道该选择哪条路径。
直接的问题可以通过将Id
拉出到Expr
生产中的导入可选组件中来解决:
Expr = Test | Id Test.
你可以做
Expr = [Id] Test .
然而,Test
的结果也可以在其开头匹配Id
,因此似乎需要进一步重构以使语法LL(1)。