- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正尝试在 lex 和 yacc 中为新语言名称 CSimple 构建我的编译。(这是该语言的手册:http://www.cs.ucsb.edu/~chris/teaching/cs160/projects/language.html)
我需要在给定输入的情况下预先打印解析语法树:
x=x+4;
还有-
procedure foo(i,j :integer) return integer { return 0;}
等等……
对于这个输入,它只打印 lexamas,编译器错误总是说:
50, x20, =50, x30, +56, 439, ; //lexemas for the first input
4, procedure7650, foo35, (50, i42, ,50, j61, :7, integer36, )7615, return767, integer7640, {7615, return7656, 039, ;41, } //lexemas for the second input
line 1: syntax error, unexpected $end, expecting FUNCTION //The error
这是我的 lex 文件:
%{
#include <stdlib.h>
#include <stdio.h>
#define YYDEBUG 0
void yyerror(const char *);
extern char* yytext;
char* func (char* token, int index);
%}
%%
boolean {func("BOOLEAN", 1);}
true {func("TRUE", 2);}
false {func("FALSE", 3);}
procedure {func("FUNCTION", 4);}
float {func("FLOAT", 5);}
char {func("CHAR", 6);}
integer {func("INT", 7);}
string {func("STRING", 8);}
intptr {func("INTPTR", 9);}
charptr {func("CHARPTR", 10);}
if {func("COND", 11);}
else {func("BLOCK", 12);}
while {func("WHILE_COND", 13);}
var {func("VARIABLE", 14);}
return {func("RETURN", 15);}
null {func("NL", 16);}
\&\& {func("AND", 17);}
\/ {func("DIVISION_OP", 18);}
\/\%.*\%\/ {func("COMMENT", 19);}
\= {func("ASSIGN", 20);}
\=\= {func("EQUAL", 21);}
\> {func("BIGGER_THEN", 22);}
\>\= {func("BIGGER_OR_EQUAL", 23);}
\< {func("SMALLER_THEN", 24);}
\<\= {func("SMALLER_OR_EQUAL", 25);}
\- {func("MINUS", 26);}
\! {func("LOGICAL_NOT", 27);}
\!\= {func("NOT_EQUAL", 28);}
\|\| {func("OR", 29);}
\+ {func("PLUS", 30);}
\* {func("MUL", 31);}
\& {func("ADDRESS_OF", 32);}
\^ {func("DEREFERANCE", 33);}
\^\^ {func("SYNTAX_ERROR", 34);}
\( {func("L_BRACKET", 35);}
\) {func("R_BRACKET", 36);}
\[ {func("L_STRING_INDEX", 37);}
\] {func("R_STRING_INDEX", 38);}
\; {func("EOS", 39);}
\{ {func("OB", 40);}
\} {func("CB", 41);}
\, {func("COMMA", 42);}
\: {func("VAR_DEC", 43);}
\_ {func("UNDERSCORE", 44);}
\|[\-]*[0-9]+\| {func("ABSULUTE_VALUE_OF_INT", 45);}
\|[a-zA-Z0-9]+\| {func("DECLARED_LENGTH_OF_STRING", 46);}
\&[0-9]* {func("LINKER_ERROR", 47);}
\&[a-zA-Z]+[\+|\-|\*|\/][a-zA-Z]+ {func("LINKER_ERROR", 48);}
\&[^STRING_TYPE\[0-9]+\]] {func("LINKER_ERROR", 49);}
[a-zA-Z]+[_]*[a-zA-Z0-9]* {func("IDENTIFIER", 50);}
[\"][a-zA-Z0-9]+[\"] {func("STRING_TYPE", 51);}
[\'].[\'] {func("CHAR_TYPE", 52);}
[\']..+[\'] {func("SYNTAX_ERROR", 53);}
[0-9]+[\.][0-9]+ {func("FLOAT_CONST", 54);}
[\-][0-9]+[\.][0-9]+ {func("FLOAT_CONST", 55);}
0|[1-9]+[0-9]* {func("INTEGER_CONST", 56);}
[\-][1-9]+[0-9]* {func("INTEGER_CONST", 57);}
0[x|X][0-9]+[a-fA-F0-9]*[a-fA-F0-9]* {func("HEX_NUMBER", 58);}
[0][^xX][1-7]+[0-7]* {func("OCTAL_NUMBER", 59);}
[0|1]+[b] {func("BINARY_NUMBER", 60);}
[^IDENTIFIER][\:] {func("SYNTAX_ERROR", 61);}
[IDENTIFIER\,]*[IDENTIFIER\:] {func("PARAMETER_LIST", 62);}
\([.*]\)\[[.*]\] {func("SYNTAX_ERROR", 63);}
[^[[IDENTIFIER|string\[integer\]|[\^][a-zA-Z]]+]][\=] {func("TYPE_MISMATCH_ERROR", 64);}
[a-zA-Z]+[=][a-zA-Z]+[=] {func("SYNTAX_ERROR", 65);}
\"\m\a\i\n\(\)\" {func("CASE_SENSETIVE_ERROR", 66);}
\([^[\)]] {func("SYNTAX_ERROR", 67);}
\{[^[\}]] {func("SYNTAX_ERROR", 68);}
if|while[^\(] {func("SYNTAX_ERROR", 69);}
else[^\{] {func("SYNTAX_ERROR", 70);}
procedure[^[[IDENTIFIER][\(][PARAMETER_LIST]*[\)]return[boolean|char|integer|intptr|charptr][\{]]] {func("FUNC_DECL_ERROR", 71);}
[PARAMETER_LIST][boolean|char|integer|intptr|charptr][\;] {func("DECL_LIST", 72);}
[IDENTIFIER\:][boolean|char|integer|intptr|charptr|string[INTEGER_CONST]][\;] {func("DECL", 73);}
var[^[DECL_LIST|DECL]] {func("DECL_ERROR", 74);}
return[^[[true|false|CHAR_TYPE|INTEGER_CONST][\;]]] {func("RETURN_ERROR", 75);}
[ ]+ {printf("76");}
--[^ \n\;\:\[\]\{\}\(\)\,]+ {func("SYNTAX_ERROR", 77);}
%%
char* func (char* token, int index)
{
printf("%d, %s", index, yytext);
return token;
}
int yywrap(void) {
return 1;
}
这是 yacc 文件:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yylex(void);
void yyerror(const char *);
typedef struct node{
char *token;
int line_number;
struct node *left;
struct node *right;
} node;
#define YYSTYPE struct node *
node *mknode(node *left, node *right, char *token);
void printtree(node *tree);
int yacc_line_number = 1;
%}
%error-verbose
%start program
%token BOOLEAN TRUE FALSE FUNCTION FLOAT CHAR INT STRING INTPTR CHARPTR DECL
%token L_BRACKET COND WHILE_COND BLOCK VARIABLE RETURN OB CB EOS FUNC_DECL_ERROR
%token AND DIVISION_OP COMMENT ASSIGN EQUAL BIGGER_THEN BIGGER_OR_EQUAL DECL_ERROR
%token SMALLER_THEN SMALLER_OR_EQUAL MINUS LOGICAL_NOT NOT_EQUAL OR PLUS DECL_LIST
%token MUL ADDRESS_OF SEMANTIC_ERROR DEREFERANCE SYNTAX_ERROR PARAMETER_LIST
%token R_BRACKET L_STRING_INDEX R_STRING_INDEX COMMA VAR_DEC NL TYPE_MISMATCH_ERROR
%token UNDERSCORE ABSULUTE_VALUE_OF_INT DECLARED_LENGTH_OF_STRING IDENTIFIER
%token STRING_TYPE CHAR_TYPE FLOAT_CONST INTEGER_CONST HEX_NUMBER OCTAL_NUMBER
%token BINARY_NUMBER CASE_SENSETIVE_ERROR LINKER_ERROR IFX RETURN_ERROR
%left EOS
//%right ASSIGN
%nonassoc IFX
%nonassoc BLOCK
%%
program:method_declarations {printtree($1);};
method_declarations:method_declaration {$$=$1;}
|method_declarations method_declaration {$$ = mknode($1,$2,"");};
method_declaration:FUNCTION IDENTIFIER L_BRACKET R_BRACKET RETURN type OB statement_block CB {$1->left=$2; $1->right=$8; $$=$1;}
|FUNCTION IDENTIFIER L_BRACKET PARAMETER_LIST type R_BRACKET RETURN type OB statement_block CB {$1->left=$2; $1->right=$10; $$=$1;};
type: BOOLEAN {$$=$1;} | CHAR {$$=$1;} | CHARPTR {$$=$1;} | INTPTR {$$=$1;} | INT {$$=$1;};
statement_block: /* none */ {$$ = 0;} | statement_block statement {$$ = mknode($1,$2,"");};
statement: simple_statement EOS {$$=$1;} | compound_statement {$$=$1;} | OB statement_block CB {$$=$2;};
simple_statement: declarative_statement {$$=$1;}| assignment_statement {$$=$1;};
declarative_statement: VARIABLE IDENTIFIER dec_statement {$1->left = $2; $1->right=$3; $$=$1;};
dec_statement: VAR_DEC type EOS {$$=$2;};
assignment_statement: IDENTIFIER {$$=$1;} | IDENTIFIER ASSIGN expression { $2->left=$1; $2->right=$3; $$=$2;};
expression: or_expression {$$=$1;};
or_expression: and_expression {$$=$1;} | or_expression OR and_expression {$2->left=$1; $2->right=$3; $$=$2;};
and_expression: relop_expression {$$=$1;} | and_expression AND relop_expression {$2->left=$1; $2->right=$3; $$=$2;};
relop_expression: ltgt_expression {$$=$1;} | relop_expression NOT_EQUAL ltgt_expression {$2->left=$1;$2->right=$3; $$=$2;} | relop_expression EQUAL ltgt_expression {$2->left=$1;$2->right=$3; $$=$2;};
ltgt_expression: addop_expression {$$=$1;} | ltgt_expression BIGGER_THEN addop_expression {$2->left=$1; $2->right=$3; $$=$2;} | ltgt_expression SMALLER_THEN addop_expression {$2->left=$1; $2->right=$3; $$=$2;} | ltgt_expression BIGGER_OR_EQUAL addop_expression {$2->left=$1; $2->right=$3; $$=$2;} | ltgt_expression SMALLER_OR_EQUAL addop_expression {$2->left=$1; $2->right=$3; $$=$2;};
addop_expression: mulop_expression {$$=$1;} | addop_expression PLUS mulop_expression {$2->left=$1; $2->right=$3; $$=$2;} | addop_expression MINUS mulop_expression {$2->left=$1; $2->right=$3; $$=$2;};
mulop_expression: term {$$=$1;} | mulop_expression MUL term {$2->left=$1; $2->right=$3; $$=$2;} | mulop_expression DIVISION_OP term {$2->left=$1; $2->right=$3; $$=$2;};
term: LOGICAL_NOT value {$1->left=$2; $$=$1;} | PLUS value {$1->left=$2; $$=$1;} | MINUS value {$1->left=$2; $$=$1;} | value {$$=$1;};
value: IDENTIFIER {$$=$1;} | STRING_TYPE {$$=$1;} | CHAR_TYPE {$$=$1;} | FLOAT_CONST {$$=$1;} | HEX_NUMBER {$$=$1;} | INTEGER_CONST {$$=$1;} | OCTAL_NUMBER {$$=$1;} | BINARY_NUMBER {$$=$1;} | TRUE {$$=$1;} | FALSE {$$=$1;} | L_BRACKET expression R_BRACKET {$$=$2;};
compound_statement: if_statement {$$=$1;} | l_statement {$$=$1;};
if_statement: COND L_BRACKET expression R_BRACKET statement %prec IFX { $1->left=$3; $1->right=$5; $$=$1;}
| COND L_BRACKET expression R_BRACKET statement BLOCK statement {$1->left=$3; $1->right = mknode($5,$6,""); $6->left=$7; $$=$1;};
l_statement: while_statement {$$=$1;};
while_statement: WHILE_COND L_BRACKET expression R_BRACKET statement {$1->left=$3; $1->right=$5; $$=$1;};
%%
#include "lex.yy.c"
int main (void) {yyparse(); return 0;}
node *mknode(node *left, node *right, char *token)
{
node *newnode = (node *)malloc(sizeof(node));
char *newstr = (char *)malloc(sizeof(token)+1);
strcpy(newstr,token);
newnode->left = left;
newnode->right = right;
newnode->token = newstr;
return(newnode);
}
void printtree(node *tree)
{
int i;
static int line1 = 0;
if(!tree){
return;
}
if (tree->line_number > yacc_line_number){
printf("\nLine(%d)",tree->line_number);
yacc_line_number = tree->line_number;
}
if (tree->left || tree->right){
if (tree->line_number == 1 && !line1){
printf("\nLine(%d)",tree->line_number);
line1 = 1;
}
if (tree->line_number>0) {
printf("\n");
for(i = 0; i < tree->line_number; i++){
printf("_");
}
printf("(");
}
}
printf(" %s ",tree->token);
if (tree->left){
printtree(tree->left);
}
if (tree->right){
printtree(tree->right);
}
if (tree->left || tree->right){
printf(")");
}
}
extern int yylineno;
void yyerror(const char *s) {
fprintf(stderr, "line %d: %s\n", yylineno, s);
}
需要帮助 :) 谢谢。
最佳答案
你的词法分析器识别标记并打印它们,但从不将它们返回给解析器,所以它读取整个输入,打印标记,然后返回 $end
(EOF, 0) 标记到解析器。解析器看到该标记并给出语法错误,因为它在输入中至少需要一个 method_declaration
。
您想要的是让您的词法分析器返回它识别出的标记,而不是继续读取更多标记。解析器将重复调用它,每次都期待下一个标记。您的解析器还设置为期望 yylval
中的词法分析器设置的 node *
值。所以你需要像这样的 lex 规则:
boolean { yylval = mknode(0, 0, "BOOLEAN"); return BOOLEAN; }
true { yylval = mknode(0, 0, "TRUE"); return TRUE; }
false { yylval = mknode(0, 0, "FALSE"); return FALSE; }
:
等等。
关于c - 莱克斯/Yacc : "line 1: syntax error, unexpected $end, expecting FUNCTION" lex compile error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41292555/
根本不是 SQL 人员。让顾问编写以下代码。 首先,它确保只选择了一所小学 - 然后,在 BEGIN 之后,如果变量 @Term 等于 3,我们想要在 IF 语句下执行操作。问题就在这里。当 @Ter
以下 javascript 将 bool 值呈现到每个语句的右侧: var reg = new RegExp(/^[\w\/].*result\b/); console.log(reg.test('p
有什么区别: x = 1 while x < 5 do x += 1 print x end 和: x = 1 while x < 5 x += 1 print x end 将 do
对于初学者来说,我是编程的“菜鸟”,所以只需了解事情的工作原理并向社区寻求帮助。 但是...我想知道的是: 我想要构建一个 Web 应用程序,两个主要用户界面之一实际上是日历产品。每个日历项目都有 8
我正在尝试制作带有图片上传选项的表单。我正在使用 express-http-proxy作为我的 API 代理和 multer按照建议。 app.use('/api', upload.any(), pr
根据this中的回答和 this问题,C++ 标准在 § 23.2.1 中声明 end() 对于所有 STL 容器都具有恒定的时间复杂度。 如果我理解正确的话: std::forward_list 只
当我使用 css 属性 align-items 时,我看不到 flex-end 值或 end 值有任何视觉差异>. align-items: end 和 align-items: flex-end 有
Sub RowRangeMove() Sheets.Add().Name = "CopySheet" With Sheets("BigDataSet - Copy")
假设第 1 到 5,000 列中有 25,000 到 50,000 行数据,每列可能有不同的行数。所有数据都是连续的,即列中没有空行,也没有空列。 考虑以下代码 Dim i As Long Dim W
我在 MYSQL 中有一个表,必须在 postgresql 中转换它。 我正在使用以下命令创建表格。 create table emp(COMPLETE BOOLEAN NOT NULL, END B
我正在尝试使用 Lark 为 BASIC 创建一个 LALR 解析器,而且我很难解决“END”语句和“END IF”等语句之间的冲突。这是语法的简化版本: %ignore /[ \t\f]+/ pro
试图理解this MSDN sample但我对这些行感到困惑: IAsyncResult result = Dns.BeginGetHostEntry(args[0], null, null); Co
我在 http://www.sgi.com/tech/stl/nth_element.html 阅读了 std::nth_element 的描述 template void nth_element(
为什么标准将 end() 定义为末尾,而不是实际末尾? 最佳答案 最好的论据是Dijkstra himself 提出的论据。 : 您希望范围的大小是一个简单的差异end - begin; 当序列退化为
我试图根据一些参数停止页面的其余部分加载;但不确定语法是否正确。 @if(dayRes + dayTri == 2){Sorry, etc @Response.End} 上面抛出这个错误: CS150
在二分搜索中,我们通常有 low 和 high 变量,并且通常有一个 while 循环来测试 low <= high,如以下代码所示(来自维基百科): int SortedArray[max] = {
我将 MS-Test 与 Visual Studio 2010 和 Visual Basic 结合使用。 在下面的函数中,代码覆盖率告诉我,有一个未检查的 block ,并且带有 “End Try”
所以今天我一直致力于使用 Protractor 为 Angular JS 应用程序设置端到端测试。为了编写更清晰的测试,我使用了 Protractor 网站上描述的 Page Object 模式。 测
所以 meteor js 的全部意义在于允许用户一次对整个堆栈进行编码,但是如果我正在使用像 django 这样的旧框架之一,可以借用meteor js的前端代码吗?比如前端的数据库同步,模板化,或者
我正在使用 wavesurfer.js 和 recorder.js 制作采样器。一切都很顺利,除了我无法使用 play([start[, end]]) 调整循环长度。 wavesurfer.seekT
我是一名优秀的程序员,十分优秀!