詳細情報を更新
Lemon を使用して要素の単純な配列を解析する際に問題が発生しています。誰かが私を啓発できますか??
この文字列 "[0 0 612 792][100 200]" を mygrammar 定義で解析しようとしていますが、パーサーは常に最初の配列要素をスキップし、最後の要素を複製します...任意のアイデア??
文法ファイルは
%token_type { char* }
%include {
#include <assert.h>
}
%parse_accept { printf("The parser has completed successfully.\n"); }
%syntax_error { fprintf(stderr, "Syntax Error\n"); }
%parse_failure { fprintf(stderr, "Parse failure\n"); }
%start_symbol program
array_value ::= INT_LITERAL(A). {printf("Av: %s\n", A);}
array_value_list ::=.
array_value_list ::= array_value_list array_value.
array_declaration ::= LBRACKET array_value_list RBRACKET.
array_list ::= array_declaration.
array_list ::= array_list array_declaration.
program ::= array_list END_TOKEN.
re2c を使用してトークンを取得し、各トークンのパーサーを呼び出すコードは次のとおりです。
while(token = scan(&scanner, buff_end)) {
// Send strings to the parser with NAME tokens
if(token == INT_LITERAL) {
name_length = scanner.cur - scanner.top;
strncpy(name_str, scanner.top, name_length);
name_str[name_length] = '\0';
//printf("Token:Pre: %s\tName: %s\n", tokenStr(token),name_str);
Parse(parser, token, name_str);
}
else {
//printf("Token: %s\n", tokenStr(token));
Parse(parser, token, 0);
}
// Execute Parse for the last time
if(token == END_TOKEN) {
Parse(parser, 0, NULL);
break;
}
}
入力文字列 "[ 0 -100 612 792][100 200]" の場合、出力は次のようになります。
Av: -100
Av: 612
Av: 792
Av: 792
Av: 200
Av: 200
お気づきのとおり、最初の要素は表示されず、最後の要素が複製されています。
レモンからの文法は次のとおりです。
State 0:
array_declaration ::= * LBRACKET array_value_list RBRACKET
array_list ::= * array_declaration
array_list ::= * array_list array_declaration
program ::= * array_list END_TOKEN
LBRACKET shift 3
array_declaration shift 1 /* because array_declaration==array_list */
array_list shift 1
program accept
State 1:
array_declaration ::= * LBRACKET array_value_list RBRACKET
array_list ::= array_list * array_declaration
program ::= array_list * END_TOKEN
LBRACKET shift 3
END_TOKEN shift 4
array_declaration shift-reduce 5 array_list ::= array_list array_declaration
State 2:
array_value ::= * INT_LITERAL
array_value_list ::= array_value_list * array_value
array_declaration ::= LBRACKET array_value_list * RBRACKET
INT_LITERAL shift-reduce 0 array_value ::= INT_LITERAL
RBRACKET shift-reduce 3 array_declaration ::= LBRACKET array_value_list RBRACKET
array_value shift-reduce 2 array_value_list ::= array_value_list array_value
State 3:
(1) array_value_list ::= *
array_value_list ::= * array_value_list array_value
array_declaration ::= LBRACKET * array_value_list RBRACKET
array_value_list shift 2
{default} reduce 1 array_value_list ::=
State 4:
(6) program ::= array_list END_TOKEN *
$ reduce 6 program ::= array_list END_TOKEN
----------------------------------------------------
Symbols:
0: $:
1: INT_LITERAL
2: LBRACKET
3: RBRACKET
4: END_TOKEN
5: error:
6: array_value: INT_LITERAL
7: array_value_list: <lambda> INT_LITERAL
8: array_declaration: LBRACKET
9: array_list: LBRACKET
10: program: LBRACKET
サンプル文字列の出力トレースは次のとおりです。
T__Input 'LBRACKET'
T__Shift 'LBRACKET', go to state 3
T__Return. Stack=[LBRACKET]
T__Input 'INT_LITERAL'
T__Reduce [array_value_list ::=], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'INT_LITERAL'
T__Return. Stack=[LBRACKET array_value_list INT_LITERAL]
T__Input 'INT_LITERAL'
T__Reduce [array_value ::= INT_LITERAL], go to state 2.
T__Shift 'array_value'
T__Reduce [array_value_list ::= array_value_list array_value], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'INT_LITERAL'
T__Return. Stack=[LBRACKET array_value_list INT_LITERAL]
T__Input 'INT_LITERAL'
T__Reduce [array_value ::= INT_LITERAL], go to state 2.
T__Shift 'array_value'
T__Reduce [array_value_list ::= array_value_list array_value], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'INT_LITERAL'
T__Return. Stack=[LBRACKET array_value_list INT_LITERAL]
T__Input 'INT_LITERAL'
T__Reduce [array_value ::= INT_LITERAL], go to state 2.
T__Shift 'array_value'
T__Reduce [array_value_list ::= array_value_list array_value], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'INT_LITERAL'
T__Return. Stack=[LBRACKET array_value_list INT_LITERAL]
T__Input 'RBRACKET'
T__Reduce [array_value ::= INT_LITERAL], go to state 2.
T__Shift 'array_value'
T__Reduce [array_value_list ::= array_value_list array_value], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'RBRACKET'
T__Return. Stack=[LBRACKET array_value_list RBRACKET]
T__Input 'LBRACKET'
T__Reduce [array_declaration ::= LBRACKET array_value_list RBRACKET], go to state 0.
T__Shift 'array_declaration', go to state 1
T__Shift 'LBRACKET', go to state 3
T__Return. Stack=[array_declaration LBRACKET]
T__Input 'INT_LITERAL'
T__Reduce [array_value_list ::=], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'INT_LITERAL'
T__Return. Stack=[array_declaration LBRACKET array_value_list INT_LITERAL]
T__Input 'INT_LITERAL'
T__Reduce [array_value ::= INT_LITERAL], go to state 2.
T__Shift 'array_value'
T__Reduce [array_value_list ::= array_value_list array_value], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'INT_LITERAL'
T__Return. Stack=[array_declaration LBRACKET array_value_list INT_LITERAL]
T__Input 'RBRACKET'
T__Reduce [array_value ::= INT_LITERAL], go to state 2.
T__Shift 'array_value'
T__Reduce [array_value_list ::= array_value_list array_value], go to state 3.
T__Shift 'array_value_list', go to state 2
T__Shift 'RBRACKET'
T__Return. Stack=[array_declaration LBRACKET array_value_list RBRACKET]
T__Input 'END_TOKEN'
T__Reduce [array_declaration ::= LBRACKET array_value_list RBRACKET], go to state 1.
T__Shift 'array_declaration'
T__Reduce [array_list ::= array_list array_declaration], go to state 0.
T__Shift 'array_list', go to state 1
T__Shift 'END_TOKEN', go to state 4
T__Return. Stack=[array_list END_TOKEN]
T__Input '$'
T__Reduce [program ::= array_list END_TOKEN], go to state 0.
T__Accept!
T__Return. Stack=]
私はこのエラーで立ち往生しています。これは、理解できない概念エラーであると確信しています。どんな助けでも大歓迎です。
ありがとう