- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Flex 和 Bison 开发一个程序。我的任务只能使用 Flex 完成(使用启动条件等),但我知道使用 Bison 可能会让我的生活更轻松。我的任务是设计一个识别编程语言声明部分的程序。它的语法和逻辑可以通过我下面的代码来理解。我的问题是我希望我的程序将代码中以“var”关键字开头的每个部分都识别为可接受的声明部分!到目前为止,我还没有做到这一点。我怎样才能成功?
下面是我的 .l (flex) 和 .y (bison) 文件。
exercise4.l
%{
#include <stdio.h>
%}
%%
[ \t\n]+ { /* Ignore all whitespaces */ }
";" { /* Ignore all semicolons */ }
":" { /* Ignore all colons */ }
var { printf("A keyword: %s\n",yytext); return VAR; }
real { printf("A variable type: %s\n",yytext); return REAL; }
boolean { printf("A variable type: %s\n",yytext); return BOOLEAN; }
integer { printf("A variable type: %s\n",yytext); return INTEGER; }
char { printf("A variable type: %s\n",yytext); return CHAR; }
[a-zA-Z][a-zA-Z0-9_]* { printf("A variable name: %s\n",yytext); return VAR_NAME; }
. { printf("Unrecognized character!\n"); return yytext[0]; }
%%
exercise4.y
%{
#include <stdio.h>
%}
%token VAR VAR_NAME REAL BOOLEAN INTEGER CHAR
%%
program : VAR typedecls ;
typedecls : typedecl | typedecls typedecl ;
typedecl : varlist ':' var_type ';' ;
varlist : VAR_NAME | varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
main( argc, argv )
int argc;
char **argv;
{
extern FILE *yyin;
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
//yylex();
yyparse();
}
yyerror(char *s)
{
printf("\nError\n");
}
#include "lex.yy.c"
最佳答案
您的扫描仪永远不会返回 :
或 ;
token (并提示 ,
无法识别)。但你的语法包含这些标记。
因此,
typedecl : varlist ':' var_type ';' ;
永远无法匹配任何内容。它没有看到它所期望的 :
,因此 var_type
是意外的。 (如果到了这一步,它就永远不会匹配 ;
了。)
我不知道您正在遵循什么古老的教程,但是 main
的 pre-ansi 原型(prototype)表明它是在上个世纪编写的(也不是在其最后几年)。作为粗略指南,我稍微更新了您的文件。
这是练习4.l;最重要的修改是我删除了手工构建的跟踪日志,因为我打算使用 Flex 的内置调试功能。我还添加了一些选项来减少编译器警告,并启用行号跟踪以在错误消息中使用。我留在了错误中。
/* File: exercise4.l */
%{
/* The bison-generated header file includes token declarations */
#include "exercise4.tab.h"
%}
%option noinput nounput noyywrap nodefault
%option yylineno
%%
[ \t\n]+ { /* Ignore all whitespaces */ }
";" { /* Ignore all semicolons. BUG */ }
":" { /* Ignore all colons. BUG */ }
var { return VAR; }
real { return REAL; }
boolean { return BOOLEAN; }
integer { return INTEGER; }
char { return CHAR; }
[a-zA-Z][a-zA-Z0-9_]* { return VAR_NAME; }
. { return yytext[0]; }
这是解析器,进行了一些修复(例如使用 1989 C 标准中的标准 C 原型(prototype)语法):
/* File: exercise4.y */
%{
/* Used in this file */
#include <stdio.h>
/* Forward and external declarations */
extern int yylineno;
int yylex();
void yyerror(const char* msg);
%}
/* These two options make error messages more informative */
%define parse.lac full
%error-verbose
%token VAR VAR_NAME REAL BOOLEAN INTEGER CHAR
%%
program : VAR typedecls
typedecls : typedecl
| typedecls typedecl
typedecl : varlist ':' var_type ';'
varlist : VAR_NAME
| varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
/* Welcome to 1990 */
int main( int argc, char** argv ) {
extern FILE *yyin;
if ( argc > 1 )
yyin = fopen( argv[1], "r" );
else
yyin = stdin;
if (!yyin) {
/* If you don't check, you'll end up segfaulting when
* yylex tries to read from NULL. Checking lets us print
* a hopefully meaningful error message.
*/
perror("Could not open file for reading");
return 1;
}
return yyparse();
}
/* Now that error messages have some content, it's worthwhile
* actually using the argument passed to yyerror */
void yyerror(const char* msg) {
fprintf(stderr, "At line %d: %s\n", yylineno, msg);
}
现在,我按顺序通过 flex、bison 和 gcc 运行这些文件,以生成可执行文件:
# The `-d` option to flex causes it to insert debugging traces. That's
# a lot less effort and a lot more useful than rolling your own trace
# logs.
flex -d -o exercise4.scan.c exercise4.l
# The `-d` option to bison causes it to output a header file, whose name
# is the same as the output file name with `.c` changed to `.h`. That's
# the file which we need to `#include` in the scanner, so that token
# names are available to scanner actions. Bison also has a debugging
# feature, but you need to use `-t` to enable it, plus add a line at
# runtime. For now, we'll leave it out.
bison -d -o exercise4.tab.c exercise4.y
# Now compile and link an executable:
gcc -Wall -g -o exercise4 exercise4.tab.c exercise4.scan.c
通常,这三个 shell 命令将进入 Makefile,以便您只需键入 makeexercise4
即可创建可执行文件。但那里并没有什么真正复杂的。
现在,我们可以尝试一下。由于我没有修复错误,您很容易就会看到问题:
var a, b: integer;
--accepting rule at line 14 ("var")
--accepting rule at line 11 (" ")
--accepting rule at line 19 ("a")
--accepting rule at line 20 (",")
--accepting rule at line 11 (" ")
--accepting rule at line 19 ("b")
--accepting rule at line 13 (":")
--accepting rule at line 11 (" ")
--accepting rule at line 17 ("integer")
At line 1: syntax error, unexpected INTEGER, expecting ':' or ','
以--
开始的行是flex的跟踪。您可以看到每个被识别的 token 。因此,当输入中遇到 :
时,就会执行第 13 行的规则。该规则是 {/* 忽略所有冒号 */}
。这就是发生的事情。
最后的错误消息是由yyerror
打印的。感谢 %errors-verbose
指令,它告诉我们它发现了什么(INTEGER
)以及它期望什么。
希望对大家有所帮助。
关于c - Flex 和 Bison : Beginning a sentence with a specific keyword,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34501734/
因此,我将在数据库中存储数百万个句子,每个句子都有一个作者。我需要能够有效地搜索句子并返回作者。现在,我希望能够拼错一个词或忘记这句话中的一两个词,并且应用程序仍然能够匹配(模糊式)。谁能指出我正确的
我知道有 Edit > Change Case菜单。但是对于句子大小写没有选择。 我如何实现这一目标?正则表达式可以做到这一点吗? 最佳答案 你可以用这个正则表达式 : 查找 (^|\.\s|…\s)
我是 Ruby 新手。这是一个使用任何语言的编程面试问题。我正在尝试用 Ruby 来做。 编写一个程序来输入给定的句子。用单词的第一个字母/#ofcharactersbetween1st&laSTLe
我有一个关于在 GATE 中使用 ANNIE 插件的 Gate API 的问题。我在 java 程序中使用了 GATE api,它适用于 50 多个文档。但是当我为超过 50 个文档运行它时,它给出了
我有一个程序要求输入一个句子,然后要求输入一个词,并告诉你那个词的位置: sentence = input("enter sentence: ").lower() askedword = input(
题目地址:https://leetcode-cn.com/problems/sentence-similarity/ 题目描述 Given two sentences words1, words2
用例 准备一个正则表达式,可以匹配'sell|sold|selling'之后的1个或2个词,并匹配变量“product” 示例 Sentence - "John wants to sell 200$
我正在尝试对一列句子执行 StringIndexer 操作,即将单词列表转换为整数列表。 例如: 输入数据集: (1, ["I", "like", "Spark"]) (2, ["I", "h
背景 希望在 JasperServer 中自动创建域。域是用于创建临时报告的数据“ View ”。列的名称必须以人类可读的方式呈现给用户。 问题 从理论上讲,组织可能希望将超过 2,000 条数据包含
我正在为我的 Sentence Splitter 应用程序寻找一个测试文件,我希望该文件能够涵盖尽可能多的案例。 谢谢! 最佳答案 阅读 Lingua::Sentence 的文档.它命名了它使用的语料
我正在尝试创建一个程序,从电视直播网站获取 html,然后使用 split 函数将所有 html 数据拆分为 channel 名称和表中当前正在播放的节目,例如如:BBC 1 -“节目名称”。我只需要
这个问题在这里已经有了答案: Combining two sed commands (2 个答案) 关闭 1 年前。 我做了这个脚本: xrandr | grep '*' | sed 's/\S*\
如何使用 GO 编程语言找到给定句子的首字母缩写词。例如,“你好,世界!”变成“HW”。到目前为止,我已经尝试拆分句子: package main import ( "bufio" "
工厂定义: public function definition() { return [ 'user_id' => function() { retu
我在 HPC 上工作,工作节点上没有互联网访问权限,训练后保存 SetFit 训练器的唯一选择是将其推送到 HuggingFace hub。如何将其保存到本地磁盘? https://github.co
当我对以下文件运行 parser.y 时,出现以下错误: myanalyzer.y: warning: 14 nonterminals useless in grammar myanalyzer.y:
我在 HPC 上工作,工作节点上没有互联网访问权限,训练后保存 SetFit 训练器的唯一选择是将其推送到 HuggingFace hub。如何将其保存到本地磁盘? https://github.co
所以我刚刚在 Shinyapps 上部署了我的电影推荐,但我仍然想改变一件事。请看下面的图片。 因为我不想把“你可能也喜欢这个”放在另一个框中,我真的不知道如何在 html/css 格式中调整它。对我
我用 python 创建了一个程序,它基本上告诉用户输入一个单词,并告诉他们它是否是回文。 我的程序: def palindrome(word): return word == word[::
我需要删除第一个字符(不是空格)之前的所有空格,并删除最后一个字符(不是空格)之后的所有空格。 看起来像这样: ' a boat has an anchor
我是一名优秀的程序员,十分优秀!