2016-09-21 82 views
0

我在網站上有相關線索(My lex pattern doesn't work to match my input file, how to correct it?我可以在lex代碼中指定模式匹配優先級嗎?

我遇到的問題是關於「greedy」lex如何進行模式匹配,我有我的lex文件:

$ cat b.l 
%{ 
#include<stdio.h> 
%} 
%% 
"12" {printf("head\n");} 
"34" {printf("tail\n");} 
.* {printf("content\n");} 
%% 

我想說的是,當遇到「12」時,打印「頭」;當遇到「34」時,打印「尾巴」,否則打印「內容」爲不包含「12」或「34」的最長匹配。

但事實是,「。*」是一個貪婪的匹配,無論我輸入什麼,它都會打印「內容」。

我的要求是,當我使用

12sdf2dfsd3sd34

爲輸入,輸出應該是

head 
content 
tail 

所以似乎還有就是2點可能的方式:

1,To s規定匹配優先級爲「。*」,只有在「12」和「34」都不匹配時才能工作。 lex支持「優先」嗎?

2,更改第三個表達式,以匹配任何不包含「12」或「34」子字符串的連續字符串。但是如何寫這個正則表達式呢?

回答

1
  1. 是否(f)lex支持優先?

(F)lex總是會產生最長的匹配。如果多個規則匹配相同的最長匹配,則選擇第一個匹配,因此在這種情況下它支持優先級。但它不支持較短匹配的優先級,也不支持非貪婪匹配。

  1. 如何匹配不包含一個或多個序列的字符串?

可以與一些工作,創造出的字符串不包含指定子串匹配正則表達式,但它是特別不容易和(f)法並不適用於此類的正則表達式提供一個簡單的語法。

一個更簡單(但效率稍低)的解決方案是匹配字符串。作爲一個大致的輪廓,你可以做到以下幾點:

"12"  { return HEAD; } 
"34"  { if (yyleng > 2) { 
      yyless(yyleng - 2); 
      return CONTENT; 
      } 
      else 
      return TAIL; 
     } 
.|\n  { yymore(); } 

這可以由通過匹配多個字符時,有沒有跳過一個分隔符的機會,更高效;改變過去的規則:

.|[^13]+ { yymore(); } 

yymore()導致保留當前令牌,以便在下次比賽追加到當前令牌,而不是開始一個新的令牌。 yyless(x)將除第一個x以外的所有字符都返回給輸入流;在這種情況下,用於在識別CONTENT令牌後重新掃描結束分隔符34

(即假定你真正想要來標記輸入流,而不是僅僅打印調試消息,這就是爲什麼我把它叫做一個輪廓的解決方案。)

+0

這確實滿足我的要求,只是改變了「12」規則是像你的「34」規則。謝謝! –

相關問題