我一直在玩一个对空格敏感的词法分析器和解析器,用于类似Python的语法。主要目标是了解解析器和词法分析器。
到目前为止我的想法是在词法分析阶段使空间无关紧要。例如,下面的输入将导致下面的输出。
if x:
x
else:
y
变为:
if x :{ x}; else :{ y};
我遇到的问题是,我不确定这是否是关于规范解决方案的良好输出。人们可以预期输出如下所示;一个表达式。
if x:{x} else:{y};
我也有一个解析器,但是它不处理显示的输出,因为它不期望在结果和替代之间出现分号。
我目前解决这个问题的想法如下:
1)预处理令牌流并将if e: {e}; else: {e};
形式的每个表达式转换为if e: {e} else: {e}
,但这似乎是一个严重的黑客攻击。
2)在解析器阶段,我可以定义if
表达式在后续主体后面有一个分号。但这对我来说似乎很难看,因为如果我想解析单行if's
,我还需要另一个案例来解析我的解析器中的if
个表达式。规则看起来类似于我的解析器中显示的规则。
IF ::= if Expr : Expr else : Expr;
| if Expr : Expr; else : Expr;
我的问题是,lex和解析空白敏感语言的规范方法是什么?我的方法是完全错误还是没有办法规避我当前的输出?
%{
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#define MAX_DEPTH 10
int nesting = 0 ;
unsigned int indent_stack[MAX_DEPTH] ;
unsigned int first[MAX_DEPTH] = { 1 };
unsigned int level = 0 ;
void process_indent(char* line) ;
%}
PUNCT [-+*/=<>:]*
ID [A-Za-z_][A-Za-z0-9_]*
INT [0-9]+
%option noyywrap
%%
^[ ]*\n {/* Ignore blank lines. */}
^[ ]*[^ \n]+ {int last = yyleng - 1;
process_indent(yytext) ;
while ((last >= 0) &&
(yytext[last] != ' ')) {
unput(yytext[last]);
last-- ;}}
"(" {printf(" "); ECHO; nesting++ ; }
")" {printf(" "); ECHO; nesting-- ; }
{ID}|{INT}|{PUNCT} {printf(" ") ; ECHO;}
[ \r] {}
\n {}
<<EOF>> { process_indent("EOF") ; return 0 ; }
%%
unsigned int white_count(char* line) {
unsigned int count = 0 ;
while (*line == ' ')
count++, line++ ;
return count ;
}
void process_indent(char* line) {
unsigned int indent = white_count(line) ;
if (nesting)
/* Ignore indents while nested. */
return ;
if (indent == indent_stack[level]) {
if (!first[level])
printf(" ;") ;
first[level] = 0 ;
return ;
}
if (indent > indent_stack[level]) {
printf("{") ;
level = level + 1;
indent_stack[level] = indent ;
first[level] = 0;
return ;
}
while (indent < indent_stack[level]) {
level = level -1;
if(level > 0)
printf(" };") ;
else
printf("};");
}
assert(level >= 0) ;
}
int main(int argc, char* argv[]) {
indent_stack[0] = 0 ;
yylex() ;
printf("\n") ;
}
```
答案 0 :(得分:0)
我不了解规范,但我所做的是以某种方式计算空白(计算空格数,空格数/标签大小,标签数量或您选择的任何内容)然后将其作为另一位数据添加到每个标记,并在每个换行符上重置该计数。
然后当我解析东西时,我可以告诉我的if语句,以期望其缩进== if.indent等的其他语句。
我也曾经将缩进设为自己的令牌,这也可以。真的取决于你的语言有什么其他语法。