Lex正在认识[作为一串字母而不是字符的一部分

时间:2015-02-25 07:59:34

标签: yacc lex

我正在编写一个简单的yacc程序来检查语法。我应该能够按照

的方式做点什么
int a[100];

我的程序中有很多打印语句,因此您可以看到发生了什么。而不是说

INT found
VAR NAME found
CHAR found
NUMBER found
CHAR found
CHAR found

它说

INT found
VAR NAME found
VAR NAME found
syntax error

在我的YACC文件中,我有

type VARNAME '[' NUM ']' ';'

在我的lex文件中

[=\-+*/%&|\[\]();{}<>!]     { //return the symbols
                fprintf(stderr,"CHAR found\n");
                            return (*yytext);
            }
[a-zA-z][a-zA-Z0-9]*        { //ID can start with any letter and end with letters and numbers.
                fprintf(stderr,"VAR NAME found\n");
                            yylval.string=strdup(yytext); 
                return(ID);
            }

这是与此问题相关的唯一代码。我所看到的与CFG没有任何不一致,所以我不确定问题是什么。

2 个答案:

答案 0 :(得分:1)

我完全同意EJP's suggestion您使用扫描仪定义末尾的简单回退规则替换那长长的特殊字符列表。但这不是你问题的原因。

原因很简单:ID的第一个字符的格式为[a-zA-z],而不是[a-zA-Z]。前一种模式匹配 Z a 之间的字符,包括 [] 。因此,[100]根据您的规范是ID

就个人而言,我建议使用Posix角色类,写作:

[[:alpha:]][[:alnum:]]*

或者,如果你想包括 _ (它也在 Z a 之间,当它发生时):

[[:alpha:]_][[:alnum:]_]*

答案 1 :(得分:0)

您发布的代码尚未完成。没有任何内容可以识别关键字int,,并且您没有识别数字文字的规则。

你过度指定了。摆脱第一条规则,并在标识符规则之后放置一个包罗万象的规则

. return yytext[0];

那样:

  1. 自动处理任何合法的单字符特殊字符。
  2. 解析器会将任何非法单字符特殊字符视为语法错误,并且会有错误恢复。