在Erlang中使用yecc解析错误:""之前的语法错误

时间:2014-04-28 22:44:47

标签: parsing erlang

我目前正在Erlang中使用yecc编写解析器。

Nonterminals expression.

Terminals '{' '}'  '+' '*' 'atom' 'app' 'integer' 'if0' 'fun' 'rec'.

Rootsymbol expression.

expression -> '{' '+' expression  expression '}' : {'AddExpression', '$3','$4'}.
expression -> '{' 'if0' expression expression expression '}' : {'if0', '$3', '$4', '$5'}.
expression -> '{' '*' expression expression '}' : {'MultExpression', '$3','$4'}.
expression -> '{' 'app' expression expression '}' : {'AppExpression', '$3','$4'}.
expression -> '{' 'fun' '{' expression '}' expression '}': {'FunExpression', '$4', '$6'}.
expression -> '{' 'rec' '{' expression expression '}' expression '}' : {'RecExpression', '$4', '$5', '$7'}.
expression -> atom : '$1'.
expression -> integer : '$1'.

我还有一个erlang项目,在解析之前对输入进行标记:

tok(X) ->
element(2, erl_scan:string(X)).

get_Value(X)->
 element(2, parse(tok(X))).

接受这些案件:

interp:get_Value("{+ {+ 4 6} 6}").
interp:get_Value("{+ 4 2}"). 

这些回报:     {' AddExpression' {' AddExpression' {integer,1,6} {integer,1,6}} {integer,1,6}} 和     {' AddExpression' {integer,1,4} {integer,1,2}}

但是这个测试用例:

interp:get_Value("{if0 3 4 5}").

返回:

{1,string_parser,["syntax error before: ","if0"]}

1 个答案:

答案 0 :(得分:1)

在语法规则中,您显示的是终端令牌的类别其值。因此,您可以匹配原子,但不能与特定原子匹配。如果您使用的是Erlang标记生成器,则为"if0"生成的标记将为{atom,Line,if0},而在您的语法中,您需要{if0,Line}标记。这就是"预处理" yecc文档的部分试图解释。

您需要一个特殊的标记器。如果要使用Erlang标记生成器,处理此方法的一种简单方法是使用预处理过程来扫描标记列表并将{atom,Line,if0}标记转换为{if0,Line}标记。