我在为ruby开发lexer。这样的雷克瑟需要清楚
区分divide“/”运算符和regex/…/操作数。
当lexer是上下文无关的(无状态的)时,它最适合构建。
关于下一个标记的lexing。
一些以“/”开头的程序文本可能是:

    ...  / abc*(foo(def,bar[q-z]*)+sam) / ...

您无法判断“/”符号是除法还是regexp的开头。
很明显,ruby必须查看上下文,否则它必须有规则
决定什么时候是模棱两可的。规则是什么?
[一种可能性:它只允许在不能发生分裂的情况下,例如在
when  [   (   ,    #{  {  if  elseif   !=  =    !~   +    ,  <<  and  or not

(2015年8月24日编辑:扩展上述列表)
这包括一切吗?还是完全不同?]

最佳答案

ruby lexer为除法运算符和regex的开头发出完全不同的标记(一个是'/',另一个是tREGEXP_BEG)。所以解析器不知道这两个实际上使用相同的源文本。
lexer如何知道要发出哪个令牌?请参见ruby源代码中的parse.y:8451
传递给lexer的parser_params结构有一个名为lex.state的成员。这是一个位字段,每个位都表示lexer状态。单个位称为BEGENDENDARGENDFNARGCMDARGMIDFNAMEDOTCLASSLABELLABELED'/'tREGEXP_BEG
当lexer看到一个ARG字符时,如果…
lexer状态对于LABELEDBEG都是真的,或者
对于MIDCLASSEXPR_MID中的任何一个,lexer状态都为true。
否则,它将发出除法运算符标记。
那么美国到底是什么意思呢?ruby源代码包含对它们的以下注释:

EXPR_BEG_bit,       /* ignore newline, +/- is a sign. */
EXPR_END_bit,       /* newline significant, +/- is an operator. */
EXPR_ENDARG_bit,        /* ditto, and unbound braces. */
EXPR_ENDFN_bit,     /* ditto, and unbound braces. */
EXPR_ARG_bit,       /* newline significant, +/- is an operator. */
EXPR_CMDARG_bit,        /* newline significant, +/- is an operator. */
EXPR_MID_bit,       /* newline significant, +/- is an operator. */
EXPR_FNAME_bit,     /* ignore newline, no reserved words. */
EXPR_DOT_bit,       /* right after `.' or `::', no reserved words. */
EXPR_CLASS_bit,     /* immediate after `class', no here document. */
EXPR_LABEL_bit,     /* flag bit, label is allowed. */
EXPR_LABELED_bit,       /* flag bit, just after a label. */

每当lexer发出一个令牌时,根据当前的lexer状态、被lexed的令牌,以及lexer可能在源文本中看到的下一个内容(它确实在许多地方进行了展望),它可能会移动到一个新的状态。
某些状态仅在读取保留关键字后输入。例如,在lexingbreaknextrescuereturn之后输入。

10-08 06:01