1

作为学习曲线练习,我使用 lex 和 yacc 将“C”头文件转换为我的 Prolog 编译器可以用来调用 dll 并从 lib 文件中提取 objs 的东西。编译器需要方法名和参数才能传递。例如

WINGDIAPI void APIENTRY glAccum (GLenum op, GLfloat value);
WINGDIAPI void APIENTRY glAlphaFunc (GLenum func, GLclampf ref);
WINGDIAPI GLboolean APIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences);
WINGDIAPI void APIENTRY glArrayElement (GLint i);

应该转化为

glAccum (unsigned op, core::real32 value);
glAlphaFunc (unsigned func, core::real32 ref);
glAreTexturesResident (integer n, pointer textures, pointer residences) -> core::char8;
glArrayElement (integer i);

在头文件的开头使用一些 typedef

typedef unsigned int GLenum;
typedef unsigned char GLboolean;
typedef unsigned int GLbitfield;
typedef signed char GLbyte;
typedef short GLshort;
typedef int GLint;
typedef int GLsizei;
typedef unsigned char GLubyte;
typedef unsigned short GLushort;
typedef unsigned int GLuint;
typedef float GLfloat;
typedef float GLclampf;
typedef double GLdouble;
typedef double GLclampd;
typedef void GLvoid;

有一个额外的表可以将“C”内置类型转换为 Prolog 内置类型。

对于我目前需要的所有标记,我都有一个工作的词法分析器。 我的问题是. 在我项目的 yacc 部分中编写规则时。如何编写一个全局规则来捕获我尚未编写规则的所有 TOKENS,以便我可以逐步处理我的项目。编写和测试每条规则。我要做的第一件事是捕获 typedef 并将它们的关联写到一个小的查找表中,以便稍后在处理函数和参数列表时,我可以插入正确的 PROLOG 原语。请注意。我不是在问如何编写规则来捕获 typedef。这我有一个粗略的想法。我在问如何在我开发我的项目时对我的“lexer”返回到“yaccer”的所有其他 TOKEN 进行全局捕获。在“词法分析器”中,您通常有一个空函数调用,对正在阅读的文本不做任何事情,例如。

“LATER”         |
“JUNK”          |
{WS}+           |
\n              |
.               ;

什么是 YACC 等价物。

4

3 回答 3

0

一旦 yyparse() 遇到与任何已知语法不匹配的输入,它就会调用 yyerror() 函数。请参阅 Yacc 手册的“错误处理”部分。

于 2013-08-21T03:18:29.783 回答
0

我猜你想要错误恢复。这是我的错误恢复实现的一部分:

line:   stmt eol
        { $$ = $1;}
        | T_NEWLINE
        { $$ = NULL;}
        | error T_NEWLINE
        {
                $$ = NULL;
                yyerrok;
        }

当出现语法错误时,第三条规则使解析器跳到下一行输入并继续解析。yyerror() 仍然被调用。不确定何时调用它,但我的猜测是在调用错误规则之前。您仍然需要阅读手册的“错误恢复”部分。

于 2013-08-21T05:04:13.143 回答
0

打印与 yacc 中的任何规则都不匹配的令牌并继续解析的方法可能是在您的 yacc 文件中添加此规则:

| error  {
    char *text;
    $<symbol_table>$->cb = malloc(sizeof(struct code_block));
    text = strdup(yytext);
    $<symbol_table>$->cb->function_call= text;
    $<symbol_table>$->cb->pos =yylineno;
    *yytext=NULL;
    printf("error: %s at line no %d\n",$<symbol_table>$->cb->function_call,$<symbol_table>$->cb->pos);**
         }
于 2015-08-27T09:26:55.093 回答