簡體   English   中英

調試解析語法

[英]Debugging Pyparsing Grammar

我正在為一種稱為C--(不是實際的C--語言)的虛構編程語言構建解析器。 我已經到了需要將語言的語法翻譯成Pyparsing可以接受的東西的階段。 不幸的是,當我解析我的輸入字符串(正確且不應導致Pyparsing錯誤)時,它無法正確解析。 我擔心這是由於語法錯誤造成的,但是當我第一次開始Pyparsing時,我似乎看不到哪里出了問題。

我已經上傳了我要從此處翻譯的語法,以供人們閱讀。

編輯:更新了保羅的建議。

這是我目前掌握的語法(我知道語法的兩行最糟糕的地方是我):

# Lexical structure definition
ifS = Keyword('if')
elseS = Keyword('else')
whileS = Keyword('while')
returnS = Keyword('return')
intVar = Keyword('int')
voidKeyword = Keyword('void')
sumdiff = Literal('+') | Literal('-')
prodquot = Literal('*') | Literal('/')
relation = Literal('<=') | Literal('<') | Literal('==') | \
           Literal('!=') | Literal('>') | Literal('=>')
lbrace = Literal('{')
rbrace = Literal('}')
lparn = Literal('(')
rparn = Literal(')')
semi = Literal(';')
comma = Literal(',')
number = Word(nums)
identifier = Word(alphas, alphanums)

# Syntax definition
term = ''
statement = ''
variable    =   intVar + identifier + semi
locals      =   ZeroOrMore(variable)
expr        =   term | OneOrMore(Group(sumdiff + term))
args        =   ZeroOrMore(OneOrMore(Group(expr + comma)) | expr)
funccall    =   Group(identifier + lparn + args + rparn)
factor      =   Group(lparn + expr + rparn) | identifier | funccall | number
term        =   factor | OneOrMore(prodquot + factor)
cond        =   Group(lparn + expr + relation + expr + rparn)
returnState =   Group(returnS + semi) | Combine(returnS + expr + semi)
assignment  =   Group(identifier + '=' + expr + semi)
proccall    =   Group(identifier + lparn + args + rparn + semi)
block       =   Group(lbrace + locals + statement + rbrace)
iteration   =   Group(whileS + cond + block)
selection   =   Group(ifS + cond + block) | Group(ifS + cond + block + elseS + block)
statement   =   OneOrMore(proccall | assignment | selection | iteration | returnState)
param       =   Group(intVar + identifier)
paramlist   =   OneOrMore(Combine(param + comma)) | param
params      =   paramlist | voidKeyword
procedure   =   Group(voidKeyword + identifier + lparn + params + rparn + block)
function    =   Group(intVar + identifier + lparn + params + rparn + block)
declaration =   variable | function | procedure
program     =   OneOrMore(declaration)

我想知道在翻譯語法時是否有任何錯誤,以及在遵循我所學語法的同時,我可以做些什么改進以簡化它。

編輯2:更新以包括新的錯誤。

這是我正在解析的輸入字符串:

int larger ( int first , int second ) { 
if ( first > second ) { 
return first ; 
} else { 
return second ; 
} 
} 

void main ( void ) { 
int count ; 
int sum ; 
int max ; 
int x ; 

x = input ( ) ; 
max = x ; 
sum = 0 ; 
count = 0 ; 

while ( x != 0 ) { 
count = count + 1 ; 
sum = sum + x ; 
max = larger ( max , x ) ; 
x = input ( ) ; 
} 

output ( count ) ; 
output ( sum ) ; 
output ( max ) ; 
} 

這是從終端運行程序時收到的錯誤消息:

/Users/Joe/Documents/Eclipse Projects/Parser/src/pyparsing.py:1156: SyntaxWarning: null string passed to Literal; use Empty() instead
other = Literal( other )
/Users/Joe/Documents/Eclipse Projects/Parser/src/pyparsing.py:1258: SyntaxWarning: null string passed to Literal; use Empty() instead
other = Literal( other )
Expected ")" (at char 30), (line:6, col:26)
None

1)將Literal("if") )更改為Keyword("if") (以此類推,向下更改為Literal("void") ),以防止與名為"ifactor"的變量的前導“ if”匹配。

2) numsalphasalphanums不是表達式,它們是字符串,可以在定義“單詞”時與Word類一起使用,以定義一些典型的字符集,例如“數字是由nums組成的單詞”,或者“標識符是一個以字母開頭,后跟零個或多個字母數字的單詞。” 所以代替:

number = nums
identifier = alphas + OneOrMore(alphanums)

你要

number = Word(nums)
identifier = Word(alphas, alphanums)

3)我想而不是Combine ,我想Group 如果希望匹配的標記連續且沒有空格,請使用Combine ,並將這些標記連接起來並作為單個字符串返回。 Combine通常用於以下情況:

realnum = Combine(Word(nums) + "." + Word(nums))

如果不使用Combine ,則解析"3.14"會返回字符串列表['3', '.', '14'] ,因此我們添加Combine使realnum的解析結果為'3.14' (然后您可以將其傳遞給解析動作以轉換為實際的浮動值3.14 )。 無中間空格的Combine強制執行也使我們避免了意外解析'The answer is 3. 10 is too much.' 並認為"3. 10"代表一個實數。

4)這不會引起您的錯誤,但是您的輸入字符串有很多額外的空格。 如果您的語法有效,則應該可以解析"int x;" 就像"int x ;"

希望其中一些提示能幫助您前進。 您是否閱讀過任何在線pyparsing文章或教程? 並請查看在線示例。 您需要掌握WordLiteralCombine等如何執行其各自的解析任務。

5)您未正確實施術語和陳述的遞歸定義。 而不是給它們分配'' ,請輸入:

term = Forward()
statement = Forward()

然后,當您使用遞歸定義實際定義它們時,請使用<<運算符(並確保將RHS括在() )。

term << (... term definition ...)
statement << (... statement definition ...)

你可以找到一個遞歸解析器的例子在這里 ,並在基本pyparsing用法介紹這里 -參見“解析列表”上的遞歸如何處理的一步一步的部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM