我在ML-Lex中创建了一个tokeniser,其定义的一部分是
datatype lexresult = STRING
| STRINGOP
| EOF
val error = fn x => TextIO.output(TextIO.stdOut,x ^ "\n")
val eof = fn () => EOF
%%
%structure myLang
digit=[0-9];
ws=[\ \t\n];
str=\"[.*]+\";
strop=\[[0-9...?\^]\];
%s alpha;
alpha=[a-zA-Z];
%%
<alpha> {alphanum}+ => (ID);
. => (error ("myLang: ignoring bad character " ^ yytext); lex());
我希望只有在&#34; alpha&#34;之后才能检测到类型ID?我知道把它写成
{alpha}+ {alphanum}* => (ID);
是一个选项,但我需要学习使用启动状态以及其他一些用途。有人可以帮我这个吗?
答案 0 :(得分:0)
您需要的信息位于the documentation which comes with SML各个地方。很多university courses have online notes which contain working examples。
您的示例代码首先要注意的是,您重载了名称alphanum
,并使用它来命名状态和模式。这可能不是一个好主意。未定义模式ID
,并且未声明结果datatype lexresult = ID
| EOF
val error = fn x => TextIO.output(TextIO.stdOut,x ^ "\n")
val eof = fn () => EOF
%%
%structure myLang
digit=[0-9];
ws=[\ \t\n];
str=\"[.*]+\";
strop=\[[0-9...?\^]\];
%s ALPHA_STATE;
alpha=[a-zA-Z];
alphanum=[a-zA-Z0-9];
%%
<INITIAL>{alpha} => (YYBEGIN ALPHA_STATE; continue());
<ALPHA_STATE>{alphanum}+ => (YYBEGIN INITIAL; TextIO.output(TextIO.stdOut,"ID\n"); ID);
. => (error ("myLang: ignoring bad character " ^ yytext); lex());
。在考虑使用状态之前你应该修复的一些基本错误 - 或者在SO上发布问题。寻求帮助代码中存在如此明显的错误并不能得到专家的帮助。 : - )
修正了这些错误后,我们就可以开始使用状态了。这是我的代码版本:
ID
您可以看到我已将lexresult
添加到ALPHA_STATE
,名为州alphanum
并添加了INITIAL
模式。现在让我们看一下状态代码的工作原理:
此程序中有两种状态,称为ALPHA_STATE
和INITIAL
(所有lex程序都具有INITIAL
默认状态)。它总是开始在<INITIAL>{alpha} =>
状态中识别。有一个规则ALPHA_STATE
表示如果你在初始状态(即不在YYBEGIN ALPHA_STATE; (* Switch from INITIAL state to ALPHA_STATE *)
continue() (* and keep going *)
中)遇到一个字母,那么它就是匹配,应该调用该动作。此规则的操作如下:
ALPHA_STATE
现在我们在<ALPHA_STATE>{alphanum} =>
,它启用为此状态定义的规则,这些规则启用规则INITIAL
。此规则上的操作将切换回use "states.lex.sml";
open myLang
val lexer =
let
fun input f =
case TextIO.inputLine f of
SOME s => s
| NONE => raise Fail "Implement proper error handling."
in
myLang.makeLexer (fn (n:int) => input TextIO.stdIn)
end
val nextToken = lexer();
状态并记录匹配。
有关使用状态(lex而非ML-lex)的更长示例,您可以在此处查看我的答案:Error while parsing comments in lex。
为了测试这个ML-LEX程序,我引用了这个有用的问题:building a lexical analyser using ml-lex,并生成了以下SML程序:
c:\Users\Brian>"%SMLNJ_HOME%\bin\sml" main.sml
Standard ML of New Jersey v110.78 [built: Sun Dec 21 15:52:08 2014]
[opening main.sml]
[opening states.lex.sml]
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[autoloading done]
structure myLang :
sig
structure UserDeclarations : <sig>
exception LexError
structure Internal : <sig>
val makeLexer : (int -> string) -> unit -> Internal.result
end
val it = () : unit
hello
ID
并且为了完整性,它生成了以下输出来演示匹配:
PHP_EOL