如何在ML-Lex中使用Start States?

时间:2015-02-11 12:53:59

标签: tokenize sml lex ml-lex

我在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);

是一个选项,但我需要学习使用启动状态以及其他一些用途。有人可以帮我这个吗?

1 个答案:

答案 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_STATEINITIAL(所有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