Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 我应该将换行符标记为单独的语句,还是在解析器上担心这一点?_Parsing_Compiler Construction_Tokenize_Lexer - Fatal编程技术网

Parsing 我应该将换行符标记为单独的语句,还是在解析器上担心这一点?

Parsing 我应该将换行符标记为单独的语句,还是在解析器上担心这一点?,parsing,compiler-construction,tokenize,lexer,Parsing,Compiler Construction,Tokenize,Lexer,我用PHP构建了一个基本的标记器,现在它解析一些类似于javascript的东西,尽管分隔语句不需要分号 a = 1 b = a + 1 echo b T_IDENTIFIER a T_EQUAL = T_NUMBER 1 T_IDENTIFIER b T_EQUAL = T_IDENTIFIER a T_NUMBER 1 T_IDENTIFIER echo T_IDENTIFIER b 这是我的第一个编译器,所以我不确定我是否准备好继续

我用PHP构建了一个基本的标记器,现在它解析一些类似于javascript的东西,尽管分隔语句不需要分号

a = 1
b = a + 1
echo b

T_IDENTIFIER  a
T_EQUAL       =
T_NUMBER      1
T_IDENTIFIER  b
T_EQUAL       =
T_IDENTIFIER  a
T_NUMBER      1
T_IDENTIFIER  echo
T_IDENTIFIER  b
这是我的第一个编译器,所以我不确定我是否准备好继续解析。我忽略lexer上的换行符,因此语句之间没有分隔符,但在我的DSL中,换行符可以用作分号的替代

我的问题是,我应该开始担心在lexer上分隔语句,还是应该修改标记器以包含换行符?

当你说“不需要分号来分隔语句”时,实际上你暗示“分隔语句需要换行符”


通过在令牌流中生成一些T_ENDOFINSTRUCTION,您可以简化工作。您的解析器将使用单独的语句。

如果换行符是语言的一部分(例如,语句有时以行边界结束),您可能应该生成ENDOFLINE作为标记。这听起来像你的案子

a = 1
b = a + 1
echo b

T_IDENTIFIER  a
T_EQUAL       =
T_NUMBER      1
T_IDENTIFIER  b
T_EQUAL       =
T_IDENTIFIER  a
T_NUMBER      1
T_IDENTIFIER  echo
T_IDENTIFIER  b
如果换行符总是空白,lexer应该把它们当作空白来使用

如果换行符有时有用,有时不有用(例如,块样式THEN子句由“THENnewline”引入),您可能应该生成两个THEN标记:一个是THEN,另一个是THENnewline


我不会担心如何在第一次尝试时就正确使用lexer,因为它们很容易修改,然后继续编写您的解析器。随着解析器的冻结,很明显,词法分析器是否需要通过生成换行符或特殊标记来提供更多帮助,然后您可以返回并相应地修改它。

如果您是langauge设计人员,选择权在您。我发现将换行符视为特殊的语言很难使用,而sometimes将换行符视为特殊(Scala、Haskell、Icon)烦人。根据语法的细节,可能很容易在解析器中分离语句,就像在Euclid和Turing中一样。例如

<Statement> ::= <Var> = <Expression>
              | echo <Expression>
              | { Block }
              | if <Expression> <Statement> else <Statement>
              | while <Expression <Statement>
<Block> ::= <Statement> <Block>
         |  <Declaration> <Block>
         |  
:==
|回音
|{Block}
|否则

|在过去几周里,我一直在设计一种语言,并手工制作lexer。我的语言不将换行符视为标记,也不需要分号来标识表达式的结尾。表达式语法本身定义语句何时结束

这在大多数情况下都很顺利,但由于我的语言中的所有语句也是表达式,因此存在一些歧义:

a(b)[方法调用]与a\n(b)[两个表达式]:我明确要求某些标记不在换行符前面,”(”是在方法调用上下文中使用的标记之一

4-2[减法]vs 4\n-2[两个表达式]:此外,与一元运算符使用相同标记的二元运算符要求它们前面没有换行符

除此之外,为了避免用户犯一些错误,我明确要求,如果两个表达式在同一行上,它们必须用分号分隔。当然,这并不涉及歧义,只是为了避免打字错误未被发现,例如:

c = a adn b

这将把
a和b
理解为一个只返回b的块,我添加了一个换行符标记。谢谢,我会看看解析器会发生什么为什么“分隔语句不需要分号”意味着“分隔语句需要换行符”.也许分隔语句所需要的只是空格,甚至什么也没有。例如,在欧几里得
a:=(b)c:=d
是两条没有任何分隔的语句。@TheodoreNorvell:好的,我明白你的意思。顺便说一句,ECMAScript也不需要半截符,但老实说,在我看来,它确实无助于可读性。它也使解析器更复杂。这个功能(语句之间没有分隔符)根据我的经验,它很容易出错。这取决于语言的细节。我用图灵编写了很多代码,遵循欧几里德方法,从来没有遇到过问题。我写过一点Scala,并且已经违反了它推断语句结尾的规则。我想说的是,设计是可能的语句没有额外的终止符或分隔符标记的语法。欧几里德/图灵示例进一步说明,它通常工作得很好。我正在考虑使用换行符来替代单独的语句。这是尴尬还是恼人?你的意思是作为分号的替代品?尴尬的部分来自以下问题:有时我们有一个长语句,出于可读性的原因,我们想把它放在多行上。要么放弃它,要么你必须引入一些复杂因素来允许异常。例如,在Fortran 77中,你在第6列中放一个非空字符,表示一行是前一行的延续。另一个例子:在C中,你使用一个反斜杠,指示宏定义在下一行继续。我没有想到。我只是希望语法简单,并且一直在研究python。我将在语句之间强制使用分号。python如何解决这个问题?只是curious@Liso22Python将换行符视为语句分隔符,但在两个环中除外有一个显式的换行符(``在换行符前面表示忽略换行符),尽管在样式指南中不鼓励这样做-我想你应该忽略它的存在。让语句跨行的首选方法是在表达式周围放置括号/括号,这样换行符就在括号/括号内,因为括号/括号内的所有空格都被忽略了。这类内容在中有记录。我将Python从列表中删除,因为我没用过它。它的规则听起来好像它们可以避免尴尬或烦人。