您需要的信息在the documentation which comes with SML 中,可以在各个地方找到。许多university courses have online notes which contain working examples。
您的示例代码首先要注意的是,您重载了名称alpha,并用它来命名state 和pattern。这可能不是一个好主意。模式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());
您可以看到我已将ID 添加到lexresult,将状态命名为ALPHA_STATE 并添加了alphanum 模式。现在让我们看看状态代码是如何工作的:
这个程序中有两个状态,它们被称为INITIAL和ALPHA_STATE(所有的lex程序都有一个INITIAL默认状态)。它总是在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 状态并记录匹配。
有关使用状态(lex 而不是 ML-lex)的更长示例,您可以在此处查看我的答案:Error while parsing comments in lex。
为了测试这个 ML-LEX 程序,我引用了这个有用的问题:building a lexical analyser using ml-lex,并生成了以下 SML 程序:
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();
为了完整起见,它生成了以下显示匹配的输出:
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