我怎么能在yacc中识别皮卡丘语言?
How could I recognise the Pikachu language in yacc?
我正在尝试做一个简单的lex&yacc程序,可以识别皮卡丘的三种声音:pi、pika和pikachu。我唯一的规则是一个标记不能连续出现 3 次。我试过这个:
%token PI PIKA PIKACHU
%%
program : program line '\n'
|
;
line: PI piWords
| PIKA pikaWords
| PIKACHU pikachuWords
;
piWords: PI
| PI pikaWords
| PI pikachuWords
;
pikaWords: PIKA
| PIKA piWords
| PIKA pikachuWords
;
pikachuWords: PIKACHU
| PIKACHU piWords
| PIKACHU pikaWords
;
%%
但这并不适用于所有组合,例如 Pika Pikachu pikachu。我怎么能重写这个?
还尝试限制 lex 中的标记,例如 {0,2} 但是当我写 pi pi pi 时它仍然有效,即使它不应该。
更新。
基于下面的想法,我确实设法完成了这个。我非常接近,我所需要的只是跟踪是否还有 2 次重复。我是这样做的:
program : program line '\n'
|
;
line: piWords
| pikaWords
| pikachuWords
;
piWords: PI
| PI pikaWords
| PI PI pikaWords
| PI pikachuWords
| PI PI pikachuWords
;
pikaWords: PIKA
| PIKA piWords
| PIKA PIKA piWords
| PIKA pikachuWords
| PIKA PIKA pikachuWords
;
pikachuWords: PIKACHU
| PIKACHU piWords
| PIKACHU PIKACHU piWords
| PIKACHU pikaWords
| PIKACHU PIKACHU pikaWords
;
你这里的语法是正确的,但需要稍微调整一下。
直觉上,每个非终结符都会跟踪你看到的最后一个终结符,这样你就不会让同一个字符串连续出现两次。您可以通过让非终端跟踪以下信息来扩展这个想法:我看到的最后一个终端是什么,我看到了多少个副本?因此,例如,当最后一个终端是 PI 时,你会有两个非终结符,一个是当 PI 读取是第一个 PI 时,另一个是当 PI 读取是第二个 PI 时。根据目前已阅读的内容,思考产生式如何在这些不同的非终结符之间转换。
我正在尝试做一个简单的lex&yacc程序,可以识别皮卡丘的三种声音:pi、pika和pikachu。我唯一的规则是一个标记不能连续出现 3 次。我试过这个:
%token PI PIKA PIKACHU
%%
program : program line '\n'
|
;
line: PI piWords
| PIKA pikaWords
| PIKACHU pikachuWords
;
piWords: PI
| PI pikaWords
| PI pikachuWords
;
pikaWords: PIKA
| PIKA piWords
| PIKA pikachuWords
;
pikachuWords: PIKACHU
| PIKACHU piWords
| PIKACHU pikaWords
;
%%
但这并不适用于所有组合,例如 Pika Pikachu pikachu。我怎么能重写这个?
还尝试限制 lex 中的标记,例如 {0,2} 但是当我写 pi pi pi 时它仍然有效,即使它不应该。
更新。
基于下面的想法,我确实设法完成了这个。我非常接近,我所需要的只是跟踪是否还有 2 次重复。我是这样做的:
program : program line '\n'
|
;
line: piWords
| pikaWords
| pikachuWords
;
piWords: PI
| PI pikaWords
| PI PI pikaWords
| PI pikachuWords
| PI PI pikachuWords
;
pikaWords: PIKA
| PIKA piWords
| PIKA PIKA piWords
| PIKA pikachuWords
| PIKA PIKA pikachuWords
;
pikachuWords: PIKACHU
| PIKACHU piWords
| PIKACHU PIKACHU piWords
| PIKACHU pikaWords
| PIKACHU PIKACHU pikaWords
;
你这里的语法是正确的,但需要稍微调整一下。
直觉上,每个非终结符都会跟踪你看到的最后一个终结符,这样你就不会让同一个字符串连续出现两次。您可以通过让非终端跟踪以下信息来扩展这个想法:我看到的最后一个终端是什么,我看到了多少个副本?因此,例如,当最后一个终端是 PI 时,你会有两个非终结符,一个是当 PI 读取是第一个 PI 时,另一个是当 PI 读取是第二个 PI 时。根据目前已阅读的内容,思考产生式如何在这些不同的非终结符之间转换。