gpt4 book ai didi

parsing - 如何在Prolog中做解析器?

转载 作者:行者123 更新时间:2023-12-02 12:02:19 24 4
gpt4 key购买 nike

我想在序言中做一个解析器。这个应该能够解析如下内容:

a = 3 + (6 * 11);

现在我只完成了这个语法。它正在工作,但我想改进它,以便拥有 id 例如 (a..z)+ 和 数字 例如 (0..9)+.

parse(-ParseTree, +Program, []):-
parsor(+Program, []).

parsor --> [].
parsor --> assign.
assign --> id, [=], expr, [;].
id --> [a] | [b].
expr --> term, (add_sub, expr ; []).
term --> factor, (mul_div, term ; []).
factor --> digit | (['('], expr, [')'] ; []).
add_sub --> [+] | [-].
mul_div --> [*] | [/].
digit --> [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9].

其次,我想在 ParseTree 变量中存储一些内容,以便像这样打印 ParseTree:

PARSE TREE:
assignment
ident(a)
assign_op
expression
term
factor
int(1)
mult_op
term
factor
int(2)
add_op
expression
term
factor
left_paren
expression
term
factor
int(3)
sub_op
...

这是我将用来打印 ParseTree 的函数:

output_result(OutputFile,ParseTree):- 
open(OutputFile,write,OutputStream),
write(OutputStream,'PARSE TREE:'),
nl(OutputStream),
writeln_term(OutputStream,0,ParseTree),
close(OutputStream).

writeln_term(Stream,Tabs,int(X)):-
write_tabs(Stream,Tabs),
writeln(Stream,int(X)).
writeln_term(Stream,Tabs,ident(X)):-
write_tabs(Stream,Tabs),
writeln(Stream,ident(X)).
writeln_term(Stream,Tabs,Term):-
functor(Term,_Functor,0), !,
write_tabs(Stream,Tabs),
writeln(Stream,Term).
writeln_term(Stream,Tabs1,Term):-
functor(Term,Functor,Arity),
write_tabs(Stream,Tabs1),
writeln(Stream,Functor),
Tabs2 is Tabs1 + 1,
writeln_args(Stream,Tabs2,Term,1,Arity).

writeln_args(Stream,Tabs,Term,N,N):-
arg(N,Term,Arg),
writeln_term(Stream,Tabs,Arg).
writeln_args(Stream,Tabs,Term,N1,M):-
arg(N1,Term,Arg),
writeln_term(Stream,Tabs,Arg),
N2 is N1 + 1,
writeln_args(Stream,Tabs,Term,N2,M).

write_tabs(_,0).
write_tabs(Stream,Num1):-
write(Stream,'\t'),
Num2 is Num1 - 1,
write_tabs(Stream,Num2).

writeln(Stream,Term):-
write(Stream,Term),
nl(Stream).

write_list(_Stream,[]).
write_list(Stream,[Ident = Value|Vars]):-
write(Stream,Ident),
write(Stream,' = '),
format(Stream,'~1f',Value),
nl(Stream),
write_list(Stream,Vars).

希望有人能帮助我。谢谢!

最佳答案

这里是对解析器的增强,可以帮助您入门。这是@CapelliC 所指出的概念的详细阐述。

parser([]) --> [].
parser(Tree) --> assign(Tree).

assign([assignment, ident(X), '=', Exp]) --> id(X), [=], expr(Exp), [;].

id(X) --> [X], { atom(X) }.

expr([expression, Term]) --> term(Term).
expr([expression, Term, Op, Exp]) --> term(Term), add_sub(Op), expr(Exp).

term([term, F]) --> factor(F).
term([term, F, Op, Term]) --> factor(F), mul_div(Op), term(Term).

factor([factor, int(N)]) --> num(N).
factor([factor, Exp]) --> ['('], expr(Exp), [')'].

add_sub(Op) --> [Op], { memberchk(Op, ['+', '-']) }.
mul_div(Op) --> [Op], { memberchk(Op, ['*', '/']) }.

num(N) --> [N], { number(N) }.

这里可能有一些小问题,但我添加到您的代码中的关键元素是:

  • 已替换 digitnum它接受任何 Prolog 术语 N其中number(N)是真的
  • 二手atom(X)识别有效的标识符
  • 添加了一个参数来保存解析给定表达式项的结果

举个例子:

| ?- phrase(parser(Tree), [a, =, 3, +, '(', 6, *, 11, ')', ;]).

Tree = [assignment,ident(a),=,[expression,[term,[factor,int(3)]],+,[expression,[term,[factor,[expression,[term,[factor,int(6)],*,[term,[factor,int(11)]]]]]]]]] ? ;

这可能不是解析树的理想表示。它可能需要根据您的需要进行一些调整,您可以通过稍微修改我所展示的内容来完成。然后您可以编写一个谓词来根据需要格式化解析树。

您还可以考虑使用嵌入式 Prolog 术语结构来代替列表结构,如下所示:

parser([]) --> [].
parser(Tree) --> assign(Tree).

assign(assignment(ident(X), '=', Exp)) --> id(X), [=], expr(Exp), [;].

id(X) --> [X], { atom(X) }.

expr(expression(Term)) --> term(Term).
expr(expression(Term, Op, Exp)) --> term(Term), add_sub(Op), expr(Exp).

term(term(F)) --> factor(F).
term(term(F, Op, Term)) --> factor(F), mul_div(Op), term(Term).

factor(factor(int(N))) --> num(N).
factor(factor(Exp)) --> ['('], expr(Exp), [')'].

add_sub(Op) --> [Op], { memberchk(Op, ['+', '-']) }.
mul_div(Op) --> [Op], { memberchk(Op, ['*', '/']) }.

num(N) --> [N], { number(N) }.

结果如下:

| ?- phrase(parser(T), [a, =, 3, +, '(', 6, *, 11, ')', ;]).

T = assignment(ident(a),=,expression(term(factor(int(3))),+,expression(term(factor(expression(term(factor(int(6)),*,term(factor(int(11)))))))))) ? ;

关于parsing - 如何在Prolog中做解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27878382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com