首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图理解标准ML (Ml)的Lex语法

试图理解标准ML (Ml)的Lex语法
EN

Stack Overflow用户
提问于 2014-04-10 04:00:10
回答 1查看 917关注 0票数 0

我在写编译器。我正处于第一阶段,试图把所有的东西都标记出来。我把这一切都写好了,但我犯了个错误。我读过三、四次文档(smlnj),这些错误并不能提供很好的信息。

我想我一定是搞砸了程序的状态更改方面,它对于创建令牌的事情很好,但是当我使用YYBEGIN转换到一个状态时,它就会爆炸。

这是我的lex文件:

代码语言:javascript
复制
type pos = int;
type lexresult = Tokens.token;

val lineNum = ErrorMsg.lineNum;
val linePos = ErrorMsg.linePos;
val commentDepth = ref 0;

fun incCom(cmDepth) = cmDepth := !cmDepth + 1;
fun decCom(cmDepth) = cmDepth := !cmDepth - 1;

fun err(p1,p2) = ErrorMsg.error p1;

fun eof() = let val pos = hd(!linePos) in Tokens.EOF(pos,pos) end;



%% 
digits=[0-9]+;

%s COMMENT STRING;

%%

<INITIAL,COMMENT>\n         => (lineNum := !lineNum+1; linePos := yypos :: !linePos; continue());
<INITIAL>"type"             => (Tokens.TYPE(yypos, yypos+4));
<INITIAL>"var"              => (Tokens.VAR(yypos,yypos+3));
<INITIAL>"function"         => (Tokens.FUNCTION(yypos, yypos+8));
<INITIAL>"break"            => (Tokens.BREAK(yypos, yypos+5));
<INITIAL>"of"               => (Tokens.OF(yypos, yypos+2));
<INITIAL>"end"              => (Tokens.END(yypos, yypos+3));
<INITIAL>"in"               => (Tokens.IN(yypos, yypos+2));
<INITIAL>"nil"              => (Tokens.NIL(yypos, yypos+3));
<INITIAL>"let"              => (Tokens.LET(yypos, yypos+3));
<INITIAL>"do"               => (Tokens.DO(yypos, yypos+2));
<INITIAL>"to"               => (Tokens.TO(yypos, yypos+2));
<INITIAL>"for"              => (Tokens.FOR(yypos, yypos+3));
<INITIAL>"while"            => (Tokens.WHILE(yypos, yypos+5));
<INITIAL>"else"             => (Tokens.ELSE(yypos, yypos+4));
<INITIAL>"then"             => (Tokens.THEN(yypos, yypos+4));
<INITIAL>"if"               => (Tokens.IF(yypos, yypos+2));
<INITIAL>"array"            => (Tokens.ARRAY(yypos, yypos+5));
<INITIAL>":="               => (Tokens.ASSIGN(yypos, yypos+2));
<INITIAL>"|"                => (Tokens.OR(yypos, yypos+1));
<INITIAL>"&"                => (Tokens.AND(yypos, yypos+1));
<INITIAL>">="               => (Tokens.GE(yypos, yypos+2));
<INITIAL>">"                => (Tokens.GT(yypos, yypos+1));
<INITIAL>"<="               => (Tokens.LE(yypos, yypos+2));
<INITIAL>"<"                => (Tokens.LT(yypos, yypos+1));
<INITIAL>"<>"               => (Tokens.NEQ(yypos, yypos+2));
<INITIAL>"="                => (Tokens.EQ(yypos, yypos+1));
<INITIAL>"/"                => (Tokens.DIVIDE(yypos, yypos+1));
<INITIAL>"*"                => (Tokens.TIMES(yypos, yypos+1));
<INITIAL>"-"                => (Tokens.MINUS(yypos, yypos+1));
<INITIAL>"+"                => (Tokens.PLUS(yypos, yypos+1));
<INITIAL>"."                => (Tokens.DOT(yypos, yypos+1));
<INITIAL>"}"                => (Tokens.RBRACE(yypos, yypos+1));
<INITIAL>"{"                => (Tokens.LBRACE(yypos, yypos+1));
<INITIAL>"]"                => (Tokens.RBRACK(yypos, yypos+1));
<INITIAL>"["                => (Tokens.LBRACK(yypos, yypos+1));
<INITIAL>")"                => (Tokens.RPAREN(yypos, yypos+1));
<INITIAL>"("                => (Tokens.LPAREN(yypos, yypos+1));
<INITIAL>";"                => (Tokens.SEMICOLON(yypos, yypos+1));
<INITIAL>":"                => (Tokens.COLON(yypos, yypos+1));
<INITIAL>","                => (Tokens.COMMA(yypos,yypos+1));


<INITIAL>{digits}           => (Tokens.INT(valOf(Int.fromString(yytext)), yypos, yypos + (size yytext)));
<INITIAL>[a-z][a-z0-9_]*    => (Tokens.ID(yytext, yypos, yypos + (size yytext)));
<INITIAL>(").*(")           => (Tokens.STRING(yytext, yypos, yypos + (size yytext)));
<INITIAL>"\""               => (YYBEGIN STRING; continue());
<STRING>"\""                => (YYBEGIN INITIAL; continue());

<INITIAL>"/*"       => (incCom commentDepth; YYBEGIN COMMENT; continue());
<COMMENT>"/*"       => (incCom commentDepth; continue());
<COMMENT>"*/"       => (print "OTHER TRACE!\n"; decCom commentDepth; if !commentDepth <= 0 then YYBEGIN INITIAL else (); continue());

<INITIAL,COMMENT>[\ \t]+    => (print "TRACE 22222\n"; continue());
<INITIAL>.                  => (ErrorMsg.error yypos ("illegal character " ^ yytext); continue());

下面是我要标记的源文件:

代码语言:javascript
复制
var , 123
/* some comment */
234 "d"

它不喜欢我的评论,也不喜欢我的字符串。谢谢你的帮助。

编辑:下面是我更新的lex文件。我已经找出了它的断裂点。我很好地检测到新注释的开头,它切换到注释状态很好,它检测到注释后的空间很好,但是它会中断,它永远不会达到耗尽int的程度。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-10 04:08:57

注释由*/而不是*\终止。(<COMMENT>"*\\" =>)。当然,您需要<COMMENT>.规则来处理评论本身。

我没有看到状态<STRING>的任何词法规则;如果没有,那么这就是字符串的问题所在。否则,我想这和那些规则有关。

编辑基于编辑的问题(不是SO的最佳使用,IMHO):

我不是SML词汇方面的专家,但在我看来,您需要一条规则来处理注释和字符串的内容(正如我在上文第一段中所说)。换句话说,当遇到终止序列以外的字符时,不存在适用于状态<COMMENT>或状态<STRING>的规则(或者,如果是注释,则是空格)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22978391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档