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 ).
4

3 回答 3

2

您的语法可能未指定。实际上,您没有定义关键字如何与标识符等其他标记分开。有些编程语言不需要将关键字与标识符分开。还有其他一些编程语言需要一些空格或布局字符。

在你的情况下,“varaasint”是一个有效的声明吗?你的语法表明了这一点。或者你必须写“var a as int”。

您可能想了解更多信息

于 2012-11-02T15:46:52.320 回答
1
type(string) --> ['string'].
type(int) --> ['int'].

(其实'不需要)

您可以使用|or ;,但这会使您返回找到的类型的方式复杂化。

于 2012-11-02T15:48:07.880 回答
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 ; []).
于 2012-11-02T19:25:48.130 回答