Flex-lexer如何匹配简单的语句?

Flex-lexer how to match simple statements?

我正在编写 flex 代码来匹配 C++ 的简单语句。喜欢:

a=b+c;
a=12;

等等

我写的是:

stat ^[a-zA-Z][a-zA-Z0-9]*+"="([a-zA-Z][a-zA-Z0-9]*|([0-9][^a-zA-Z])+)+(("+"|"-"|"*"|"/")([a-zA-Z][a-zA-Z0-9]*|([0-9][^a-zA-Z])+)+)*+";"$

接受语句 c=a+b*23; a=2+32; 但不接受 a=2+3;.

以上代码为:If a variable name starts from a-zA-Z then accept it, but if it starts with a number then reject this.

所以 ([a-zA-Z][a-zA-Z0-9]*|([0-9][^a-zA-Z])+) 将匹配如果以字母开头的单词可以是数字或字母,但如果有数字则下一个字符应该是数字(对于像 a=10; 这样的语句)。

表达式([0-9][^a-zA-Z])+只匹配偶数位数的数字。您的意思可能是 ([0-9][^a-zA-Z]*)+(为第二个字符插入星号 class 使其可选)。

一般说明:正则表达式将接受您打算接受的超集。通常不可能使用正则表达式来解析嵌套表达式。为此你需要一个真正的解析器。

我建议编写递归下降解析器,例如使用 PEG(解析器表达式语法)。这些功能非常强大,但编写起来简单易懂。

另请参阅:

词法扫描器背后的想法是它识别单个标记(标识符、文字常量、运算符、标点符号等),而不是像语句这样的完整语法结构。

尝试使用正则表达式模式来识别像表达式这样复杂的东西几乎注定会失败,即使是没有括号的表达式。这些可能会被正则表达式识别,但处理所有极端情况会使模式不必要地复杂化。一旦你添加了括号,这个任务就变得不可能了(至少对于 flex 的模式语言来说,与大多数正则表达式库不同,它确实是规则的)。

相反,使用扫描器将输入分成简单的部分(标记)并丢弃可忽略的序列(空白和常量)。然后可以通过上下文无关的解析器分析生成的标记。