根据我的 BASIC 语法正确匹配一组标记

问题描述

我正在用 Prolog 编写 BASIC 解释器。 DCG 有点棘手,这就是我今天在这里遇到麻烦的原因。

这是我的语法。

bool --> [true].
bool --> [false].

is_num_char(AD) :- AD = '.'; (atom_codes(AD,[D]),D >= 48,D =< 57).
number --> [].
number --> is_num_char,number.

quotes_on_atom(S) :- atom_chars(S,['"' | C]),last(C,'"').
string --> quotes_on_atom.

literal --> bool; number; string.
variable --> \+ literal.

assignment --> string,['='],expr.

equal --> expr,['=='],expr.
not_equal --> expr,['!='],expr.

if --> [if],expr,[then],expr.

for_decl --> [for],assignment,[to],number,[step],number.
for_next --> [next],integer.

expr --> literal; variable; assignment;
        equal; not_equal; if; for_decl; for_next.

这是我的 main 目标:

main :-
    % expected: [for,[i,'=',0],to,'5',step,'1']
    trace,phrase(expr,[for,i,'0','1']).

这是我得到的错误uncaught exception: error(existence_error(procedure,is_num_char/2),number/0)

堆栈跟踪揭示了这一点:

The debugger will first creep -- showing everything (trace)
      1    1  Call: phrase(expr,=,'1']) ? 
      2    2  Call: expr([for,'1'],_335) ? 
      3    3  Call: literal([for,_335) ? 
      4    4  Call: bool([for,_335) ? 
      4    4  Fail: bool([for,_335) ? 
      4    4  Call: number([for,_335) ? 
      4    4  Exit: number([for,'1']) ? 
      3    3  Exit: literal([for,'1']) ? 
      2    2  Exit: expr([for,'1']) ? 
      2    2  Redo: expr([for,'1']) ? 
      3    3  Redo: literal([for,'1']) ? 
      4    4  Redo: number([for,'1']) ? 
      5    5  Call: is_num_char([for,_446) ? 
      5    5  Exception: is_num_char([for,_459) ? 
      4    4  Exception: number([for,_335) ? 
      3    3  Exception: literal([for,_335) ? 
      2    2  Exception: expr([for,_335) ? 
      1    1  Exception: phrase(expr,'1']) ? 
uncaught exception: error(existence_error(procedure,number/0)
{trace}

似乎 is_num_char 正在传递整个令牌列表以及其他内容。鉴于 number 规则只接受一个参数,我不明白为什么会发生这种情况。此外,令牌列表以 number 开始是很奇怪的。它应该与 for_decl 统一。如果您了解 Prolog DCG,请告诉我我在这里做错了什么。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)