解析器实现

4

你好,我正在尝试实现一个解析器,用于处理一个语法结构简单的语言。

program ::= "program" declarations "begin" statements "end"
declaration ::= "var" ident "as" type
type ::= "string" | "int"

我已经完成前两项,我该如何编写类型语法?
program( prog( DECLS, STATS ) ) -->
[ 'program' ], declarations( DECLS ),
[ 'begin' ], statements( STATS ), [ 'end' ].

declaration( decl( IDENT, TYPE ) ) -->
[ 'var' ], ident( IDENT ), [ 'as' ], type( TYPE ).

当我按照上述规则更改语法时,我将使用SICStus进行测试。我只是在Wordpad中编辑带有.sp文件的语法。 - user1794576
3个回答

2
你的语法可能未充分说明。实际上,你没有定义关键字与标识符等其他令牌之间如何分隔。有些编程语言不需要将关键字与标识符分开。而其他编程语言则需要一些空格或布局字符。
在你的情况下,“varaasint”是否是有效声明?你的语法表明是的。或者你必须写成“var a as int”。
你可能想查看此答案了解更多信息。

1
type(string) --> ['string'].
type(int) --> ['int'].

实际上,不需要使用'

你可以使用|;,但这会使你返回找到的类型的方式变得复杂。


我也正在尝试执行此赋值语句:ident operator expr。你可以帮忙吗? - user1794576
@user1794576听起来相当简单;assign_stmt(...):- ident(...)operator(...)expr(...)。对于表达式,您应该从语法中删除左递归:https://en.wikipedia.org/wiki/Left_recursion#Removing_left_recursion - Thanos Tintinidis

1

你错过了 statements 规则!

无论如何,DCG规则只是Prolog上的纯语法糖,因此您可以使用任何喜欢的Prolog功能。如果您需要保持语法紧凑:

type(type(T)) --> [T], {memberchk(T, [int, string])}.

花括号允许将通用Prolog与语法规则混合使用。

正如@false所指出的那样,您的语法仅在您拥有分词器并且可以将输入拆分并丢弃空格时才有用。或者您可以更直接地处理它,使用此模式(注意,未经测试的代码):

program( prog( DECLS, STATS ) ) -->
   s, "program", s, declarations( DECLS ),
   s, "begin", s, statements( STATS ), s, "end", s.

declaration( decl( IDENT, TYPE ) ) -->
   "var", s, ident( IDENT ), s, "as", s, type( TYPE ).

declarations([D|Ds]) --> declaration(D), declarations(Ds).
declarations([]) --> [].

type(type(int)) --> "int".
type(type(string)) --> "string".

% skip 1 or more whitespace
s --> (" " ; "\n"), (s ; []).

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接