2014-06-18 66 views
0

我想组成一个“经典”的基本语法与多一点自由格式的混合,例如:如何强制野牛即时编译

a=5:b=6:c=a+b   // writing several instructrions into a single line 
       // using colon as separator 
       // but eliminating mandatory terminals (like ';' in c) 

while (x < 3) {  // condition has mandatory parentheses around, but 
x=x+1:y=y+2   // body of 'while' may also have multi-statements line(s) 
z=y+y    // and may have several lines as well 
} 

为了实现它,我建立了下列规则。我的Flex确实职责,正确地消除了不必要的换行等:

^[ \t\r\n]*\n   /*ignore empty line */ 
\/\/.*\n ;   /* skip comment */ 
[ \t\r\n]+ ;   /* ignore whitespace */ 
\{[ \t\r\n]*\} ;  return EMPTY; 
\{[ \t\r\n]* ;   return '{'; 
\}[ \t\r\n]* ;   return '}'; 

不幸的是,语句后面加上冒号不强制编译器做立即编译。 然而,在后面的代码被编译的过程中,往往预计会在后半部分。 这里是我的野牛档案的结构。

%type <nPtr> stmt stmt_list expr 

%% 
line: 
    line stmt_list ':' {  // <-- this is my problem 
     ex($2); freeNode($2); 
     } 
    | line stmt_list '\n' { 
     ex($2); freeNode($2); 
     } 
    | /* NULL */ 
    ; 

stmt: VARIABLE '=' expr  { $$ = opr('=', 2, $3, id($1)); } 
    | PORT '=' expr   { $$ = opr('=', 2, $3, id($1)); } 
    | .... etc. 
    | WHILE '(' expr ')' EMPTY { $$ = opr(WHILE, 1, $3); } 
    | WHILE '(' expr ')' stmt_list { $$ = opr(WHILE, 2, $3, $5); } 
    ; 

stmt_list: 
    stmt    { $$ = $1; } 
    | '{' stmt_list '}'  { $$ = $2; } 
    | '{' error '}'   { errorflag=1; } 
    | error '\n'   { errorflag=1; } 
    ; 

expr: 
    INTEGER    { $$ = con($1); } 
    | VARIABLE   { $$ = id($1); } 
    | .... etc. 
    | '(' expr ')'   { $$ = $2; } 
    ; 

我该如何修改它以达到预期的行为?

+0

“即时编译”是什么意思?预期的行为是什么以及发生了什么?尝试包括[sscce](http://sscce.org) –

回答

2

野牛行动要记住的重要一点是,它们在右手边已经完全解析时执行。

考虑两个简单的递归制作:

a: N a | %empty ; 

a: a N | %empty ; 

让我们将它们应用到输入:

N1 N2 N3 

有了正确的递归情况(第一次),产品将如下(下标只是为了清楚):

a0 → N1 a1 a1 → N2 a2 a2 → N3 a3 a3 → ε

和分析树:

a0
+-----+-----+
| |
| a1
| +---+---+
| | |
| | a2
| | +-+-+
| | | |
| | | a3
| | | |
N1 N2 N3 ε

而左递归一个(第二个),产生:

a0 → a1 N3 a1 → a2 N2 a2 → a3 N1 a3 → ε

和分析树是:

a0
+-----+-----+
| |
a1 |
+---+---+ |
| | |
a2 | |
+-+-+ | |
| | | |
a3 | | |
| | | |
ε N1 N2 N3

需要注意的重要一点是,在右递归的情况下,所有生成包括整个输入字符串,因此解析器操作发生在从右到左。相反,在左递归的情况下,产生式连续产生字符串的前缀,并且分析器动作发生在从左到右

总之,如果您希望您的操作从左到右发生,请使用左递归。

2

我看到了一些严重的问题,你的榜样

  • 你的语法使用'\n'(新行)令牌,但你的词法分析器忽略换行符和永远不会返回它们,所以涉及到新行的规则永远不能减少
  • 你举的例子说,多语句行(用冒号)可以在WHILE机构出现,但你的语法不允许这样
因为这些

,解析器甚至无法解析SE正确地输入你的输入行,更不用说进入循环了。