"< *>"的含义在lex

时间:2013-03-21 06:34:36

标签: bison yacc lex flex-lexer

我知道,我们可以在lex中定义一些条件,匹配:

1.<DIRECTIVE>{STRING} {printf("Matching the DIRECTIVE state!");}
2.<REFERENCE>{INTEGER} {printf("Matching the REFERNCE state!");}
3.[\n] {printf("Matching the INITIAL state?");}

4.<*>{DOBULE} {printf("Matching all state include INITIAL? Seem not!");}

如何以正确的方式使用状态?第3和第4行的条件有什么不同?

整个.l文件,由我剪切,现在它只是为了实现一个参考。当我运行它,它可以很好地工作,但它总是说“行:4:错误:语法错误”,我不知道为什么!我的test.vm只有2行文字。

%{
/**支持了所有的token,不支持转义和多行注释*/
#include<stdio.h>
#include<string.h>
#include "context.h"
#include "bool.h"
#include "vtl4.tab.h"

extern int yylex();
/**bracket标志*/
int bracket_flag = 0;
/**引用标志*/
int ref_flag = 0;
/**多行注释标记*/
int mul_comment_flag = 0;
%}
%option stack
%option noyywrap yylineno

%x REF
VAR_NAME ([_a-zA-Z]+[a-zA-Z0-9_\-]*)
%%
/**这里去除$#\n防止覆盖状态REF和DIRECTIVE*/
[^$\n#]*? {printf("text:%s\n",yytext);yylval.string = yytext; return CONTENT;}
/**换行单独取出来,还没清楚为什么*/
\n {printf("newLine:%s\n",yytext);yylval.string = yytext; return CONTENT;}

/**添加^$防止只匹配最后一个变量
 例如:<p class="$b">$a $b</p> 只匹配了最后一个$b
 */
[^#$]*?/"$" {BEGIN REF;printf("begin ref text:%s\n",yytext);yylval.string = yytext; return       CONTENT;}

<REF>"$"|"$!"/"{"?{VAR_NAME} {ref_flag++;printf("$:%s\n",yytext);return DOLLAR;}
<REF>"{" {printf("{:%s\n",yytext);return BRACE;}
<DIRECTIVE>"}" {printf("}:%s\n",yytext);return BRACE_CLOSE;}
<REF>{VAR_NAME}/[^0-9A-Za-z_\-] {
    printf("ref name:%s\n",yytext);
    ref_flag--;
    yylval.sym = find_symbol(yytext);
    return ID;
}
<REF>[ /t"="\n] {BEGIN INITIAL; printf("ref end:%s\n",yytext);}
<REF>[}] {printf("}:%s\n",yytext);return BRACE_CLOSE;}

<<EOF>> {printf("lex end:%s\n",yytext);return LEX_EOF;}
%%

整个.y文件:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bool.h"
#include "parser.h"
#include "context.h"
#include "vtl4.tab.h"

extern FILE * yyin;
extern FILE * yyout;
int yylex();
#define YYDEBUG 1
%}
/*priority level*/
%union {
struct simpleNode *ast;
double d;
int i;
bool b;
char* string;
struct symbol *sym;
}

%token ADD SUB MUL DIV MOD EQUAL PARENTHESIS CLOSE_PARENTHESIS BRACE BRACE_CLOSE  LOGICAL_AND LOGICAL_OR LOGIC_EQUAL LOGICAL_LT LOGICAL_LE LOGICAL_GT LOGICAL_GE LOGICAL_NOT_EQUALS

%token  LEX_EOF

%token <string> CONTENT STRING_LITERAL SINGLE_LINE_COMMENT MULTI_LINE_COMMENT
%token <b> BOOL

%token INTEGER_LITERAL

%token <d> DOUBLE_LITERAL

%token DOLLAR

%token <sym> ID

%token HASH SET PARSE IF ELSE ELSEIF FOREACH IN END

%type <ast> root statements statement reference content

%start root

%%
/*JJTPROCESS*/
root:statements LEX_EOF {printf("yacc root\n");$$ = process($1);}
;

statements
: statement {printf("yacc statements:statement\n"); $$ = $1; }
| statements statement {printf("yacc statements:statements statement\n"); $$ =     add_ybrother($1,$2);}
;

statement
 : reference {printf("yacc statement:ref\n"); $$ = $1;}
| content
;

reference
: DOLLAR ID {printf("yacc ref\n");$$ = reference($2);}
 ;

content
: CONTENT {$$ = text(NULL);}
;

%%
int main(){
printf("BEGIN:\n");
FILE *src;
src = fopen("test.vm","r");
yyin = src;
int result = yyparse();
fclose(src);
return result;
}

1 个答案:

答案 0 :(得分:1)

首先,开始条件不是Lex的特色。它们是GNU Flex的一个特性。

语法<*>确实记录为“此规则将在任何州无条件触发”。

您可能知道,条件可以是排他性的(使用%x定义)或包含(使用%s定义)。

如果您在没有任何条件的情况下编写规则,则它在INITIAL状态中处于活动状态,并且在任何包含的状态中都处于活动状态:包含意味着“在此状态下将指定无条件的规则将处于活动状态”。

如果当前状态是一个独有的状态,则没有任何条件的规则不会处于活动状态:它会排除没有条件的规则。

<*>语法意味着规则将在所有状态中激活,包括exlusive规则。

如果规则没有<...>条件语法,则表示该规则仅在INITIAL状态或包含状态的状态下激活。

解析器中仍然存在很多问题。请记住,最长的匹配规则是在输入中的任何点触发的规则,并且可能被误解为启动条件不起作用。如果输入为catalog且某些符合条件的规则要与cat匹配,则匹配c的规则与<*>相关并不重要。这不是最长的比赛。