我在 Lexer.x 中有兩個非常相似的模式,第一是數字,第二是位元組。他們來了。
$digit=0-9
$byte=[a-f0-9]
$digit { \s -> TNum (readRational s) }
$digit .$digit { \s -> TNum (readRational s) }
$digit .$digit e$digit { \s -> TNum (readRational s) }
$digit e$digit { \s -> TNum (readRational s) }
$byte$byte { \s -> TByte (encodeUtf8(pack s)) }
我有 Parser.y
%token
cnst { TNum $$}
byte { TByte $$}
'[' { TOSB }
']' { TCSB }
%%
Expr:
'[' byte ']' {$1}
| const {$1}
當我寫的時候,我得到了。
[ 11 ] parse error
11 ok
但是當我在 Lexer 中將位元組模式放在數字之前
$digit=0-9
$byte=[a-f0-9]
$byte$byte { \s -> TByte (encodeUtf8(pack s)) }
$digit { \s -> TNum (readRational s) }
$digit .$digit { \s -> TNum (readRational s) }
$digit .$digit e$digit { \s -> TNum (readRational s) }
$digit e$digit { \s -> TNum (readRational s) }
我有
[ 11 ] ok
11 parse error
我認為這是因為 Lexer 從字串中生成標記,然后將它們提供給決議器。當決議器等待位元組令牌時,它得到了數字令牌,決議器沒有機會從這個值生成另一個令牌。在這種情況下我應該怎么做?
uj5u.com熱心網友回復:
在這種情況下,您應該推遲決議。例如,您可以創建一個TNumByte資料建構式,將值存盤為String:
Token
= TByte ByteString
| TNum Rational
| TNumByte String
-- …
對于一個$digits序列,我們還不清楚是否必須將其解釋為位元組或數字,因此我們TNumByte為此構造了 a :
$digit=0-9
$byte=[a-f0-9]
$digit$digit { TNumByte }
$byte$byte { \s -> TByte (encodeUtf8(pack s)) }
$digit { \s -> TNum (readRational s) }
$digit .$digit { \s -> TNum (readRational s) }
$digit .$digit e$digit { \s -> TNum (readRational s) }
$digit e$digit { \s -> TNum (readRational s) }
然后在決議器中我們可以根據背景關系來決定:
%token
cnst { TNum $$ }
byte { TByte $$ }
numbyte { TNumByte $$ } -- ?? can be int or byte
'[' { TOSB }
']' { TCSB }
%%
Expr
: '[' byte ']' { $2 }
| '[' numbyte ']' { encodeUtf8(pack $2) } -- ?? interpret as byte
| const { $1 }
| numbyte { readRational $1 } -- ?? interpret as int
;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/398718.html
