我需要做的是将原子分解为令牌。例如:
tokenize_string('Hello, World!', L).
会统一L=['Hello',',','World','!']
。完全一样tokenize_atom/2
。但是当我尝试使用tokenize_atom/2
非拉丁字母时它失败了。有没有通用的替代品,或者我怎么写一个?提前致谢。
好吧,您可以编写自己的词法分析器。例如,我可以向您展示我的算术表达式解析器中的词法分析器。
:- use_module(library(http/dcg_basics)).
%
% lexer
%
lex([H | T]) -->
lexem_t(H), !,
lex(T).
lex([]) -->
[].
lexem_t(L) --> trashes, lexem(L), trashes.
trashes --> trash, !, trashes.
trashes --> [].
trash --> comment_marker(End), !, string(_), End.
trash --> white.
comment_marker("*)") --> "(*".
comment_marker("*/") --> "/*".
hex_start --> "0X".
hex_start --> "0x".
lexem(open) --> "(".
lexem(close) --> ")".
lexem(+) --> "+".
lexem(-) --> "-".
lexem(*) --> "*".
lexem(/) --> "/".
lexem(^) --> "^".
lexem(,) --> ",".
lexem(!) --> "!".
lexem(N) --> hex_start, !, xinteger(N). % this handles hex numbers
lexem(N) --> number(N). % this handles integers/floats
lexem(var(A)) --> identifier_c(L), {string_to_atom(L, A)}.
identifier_c([H | T]) --> alpha(H), !, many_alnum(T).
alpha(H) --> [H], {code_type(H, alpha)}.
alnum(H) --> [H], {code_type(H, alnum)}.
many_alnum([H | T]) --> alnum(H), !, many_alnum(T).
many_alnum([]) --> [].
这个怎么运作:
?- phrase(lex(L), "abc 123 привет 123.4e5 !+- 0xabc,,,"), write(L).
[var(abc), 123, var(привет), 1.234e+007, !, +, -, 2748, (,), (,), (,)]