prolog中的字符串标记化

prolog中的字符串标记化,prolog,tokenize,dcg,Prolog,Tokenize,Dcg,我在文本文件“grammar.txt”中有以下上下文无关语法 S ::= a S b S ::= [] 我正在打开这个文件,能够阅读prolog中的每一行。 现在我想标记每一行并生成一个列表,如 L=[['S','::=','a','S','b'],['S','::=','#']] ('#' represents empty) 我如何才能做到这一点?在DCG中编写规范。我给你的基本(未经测试),你需要完善它 parse_grammar([Rule|Rules]) --> parse

我在文本文件“grammar.txt”中有以下上下文无关语法

S ::= a S b
S ::= []
我正在打开这个文件,能够阅读prolog中的每一行。 现在我想标记每一行并生成一个列表,如

L=[['S','::=','a','S','b'],['S','::=','#']]  ('#' represents empty)

我如何才能做到这一点?

在DCG中编写规范。我给你的基本(未经测试),你需要完善它

parse_grammar([Rule|Rules]) -->
 parse_rule(Rule),
 parse_grammar(Rules).
parse_grammar([]) --> [].

parse_rule([NT, '::=' | Body]) -->
  parse_symbol(NT),
  skip_space,
  "::=",
  skip_space,
  parse_symbols(Body),
  skip_space, !.  % the cut is required if you use findall/3 (see below)

parse_symbols([S|Rest]) -->
  parse_symbol(S),
  skip_space,
  parse_symbols(Rest).
parse_symbols([]) --> [].

parse_symbol(S) -->
  [C], {code_type(C, alpha), atom_codes(S, [C])}.

skip_space -->
  [C], {code_type(C, space)}, skip_space.
skip_space --> [].
这将使用以下顶级解析整个文件:

  ...,
  read_file_to_codes('grammar.txt', Codes),
  phrase(parse_grammar(Grammar), Codes, [])).
您说您每次读取文件1行:然后使用

  ...
  findall(R, (get_line(L), phrase(parse_rule(R), L, [])), Grammar).

HTH

我尝试过使用您的代码,但它不起作用。我正在努力改进它。你能告诉我这部分代码做什么吗…
parse_-symbol-->[C],{code_-type(C,alpha),atom_-code(S[C])。跳过空间-->[C],{code\u type(C,空格)},跳过空间。跳过空格-->[]。
我正在以以下方式执行,并显示一条错误消息,提示
11?-parse_语法([S:=a S b])。错误:语法错误:运算符预期错误:parse_grammar([S ERROR:*here**ERROR::=a S b])。
…这是错误的查询方式吗您必须使用内置短语/3与解析器交互,例如:code=“S::=a S b”、短语(parse_grammar(grammar)、代码、[])、writeln(grammar)。将打印:[[S,:=,a,S,b]]是的,我知道了。但是你能告诉我
[C],{code\u type(C,alpha),atom\u code(s,[C])}有什么用吗?
请注意,如果你使用SWI,你可以使用
phrase\u from\u file(phrase,file)
更有效地解析文件。我编辑了@chac对此的回应。