Lex:为什么我的所有代币都是未定义的

时间:2015-10-27 22:18:19

标签: c++ yacc lex

当g ++编译lex.yy.c

时,我的所有令牌都是未定义的

这可能与使用C ++而不是c?

有关

所有令牌都在yacc解析器源中使用%token声明定义:gh.y

以下是yacc代码的相关部分:

%skeleton "lalr1.cc"
%start game

%union {
    char* str;
    int num;
    GMPARTptr gmpart;
}

%token DOTMAP DOTM DOTR DOTC DOTD DOTT DOTO DOTU DOTV COMMA;
%token PLUS MINUS SLASH SEMI RBRACKET LBRACKET;
%token PCTDOL PCTSLASH PCTT PCTAT;

%token <int> INT;
%token <str> WORD FILEPART STRING QUOTE;
%type <str> image fname label animation roomname description
%type <str> normfname
%type <int> xcoord ycoord
%type <str>roomid ID charname

我的lex输入的第一部分:

%{
#include <stdio.h>
#include <string.h>
#include "mkscript.h"
#include "gh.tab.h"
%}

DIGIT   [0-9]
STARTCHAR       [_a-zA-Z]
WORDCHAR        {DIGIT}|{STARTCHAR}
FILECHAR        {WORDCHAR}|[-.+@#$%()]
FILECHAR1       {FILECHAR}|[/" ]
FILECHAR2       {FILECHAR}|[/' ]
 /* special "start states" for matching */
%s DESC

%%
\.map   return DOTMAP;
\.m     return DOTM;
\.r     return DOTR;
\.c     return DOTC;
\.d     return DOTD;
\.t     return DOTT;
\.o     return DOTO;
\.u     return DOTU;
\.v     return DOTV;

但是当我编译lexx的输出时,我得到所有令牌名称的“未在此范围内声明”。

以下是我的错误日志文件的前几行:

 g++ -DYYERROR_VERBOSE   -c -o lex.yy.o lex.yy.c
    ghlex.l: In function ‘int yylex()’:
    ghlex.l:18:8: error: ‘DOTMAP’ was not declared in this scope
      \.map return DOTMAP;
                   ^
    ghlex.l:19:8: error: ‘DOTM’ was not declared in this scope
        \.m return DOTM;
                   ^

=============================================== ========================

可以在以下位置找到完整的lex和yacc输入文件,makefile和make中的错误日志: http://conchord.org/code/ 分别在文件ghlex.l,gh.y,makefile和log中。

2 个答案:

答案 0 :(得分:0)

基本问题是行public void onClick(View v) { int id = v.getId(); if (id == MyR.getResId(getApplicationContext(), "id", "title_left_image ")){ exit(); } } ,它导致bison生成与普通lex不兼容的非标准解析器。相反,解析器在%skeleton "lalr1.cc"类中被激活。

使用flex,您可以构建一个与此模式兼容的解析器,但是您需要一个适当的parser宏声明,提供YY_DECL个额外参数,并且您使用yylex前缀所有令牌名称。

最容易解决的问题可能只是摆脱它。

答案 1 :(得分:0)

我包含了我在extern“C”中从解析器调用的所有函数(例如addRoom)。然后进行了一些调整,并进行了编译和链接。