您好我正在尝试使用类似语法的简单语言实现解析器。
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 ).
答案 0 :(得分:2)
您的语法可能未被指定。实际上,您没有定义关键字如何与其他标记(如标识符)分开。有编程语言,您不需要将标识符与标识符分开。还有其他编程语言需要一些空格或布局字符。
在您的情况下,“varaasint”是否是有效的声明?你的语法表明了这一点。或者你必须写“var a as int”。
您可能需要查看this answer for more。
答案 1 :(得分:2)
type(string) --> ['string'].
type(int) --> ['int'].
(实际上'
不是必需的)
您可以使用|
或;
,但这会使您返回所找到类型的方式复杂化。
答案 2 :(得分: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 ; []).