سؤال

أنا في بناء محلل بالنسبة وهمي لغة برمجة تسمى ج - (لا الفعلية ج-اللغة).لقد وصلت إلى المرحلة حيث كنت بحاجة إلى ترجمة اللغة والنحو إلى شيء 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".

2) nums, alphas, ، alphanums ليست تعبيرات هم السلاسل التي يمكن استخدامها مع كلمة الفصل في تحديد بعض نموذجية مجموعات من الأحرف عند تحديد "الكلمات" مثل "عددا هي كلمة تتكون من nums" ، أو "معرف هي الكلمة التي تبدأ بحرف ألفا ، تليها صفر أو أكثر alphanums." وذلك بدلا من:

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). Combines إنفاذ لا تتدخل بيضاء يبقى لنا أيضا من قصد تحليل 'The answer is 3. 10 is too much.' والتفكير "3. 10" يمثل العدد الحقيقي.

4) هذا لا ينبغي أن يسبب خطأ ، ولكن سلسلة الإدخال قد الكثير من مسافات إضافية.إذا كنت تحصل على قواعد العمل ، يجب أن تكون قادرا على تحليل "int x;" فقط وكذلك "int x ;".

آمل أن بعض هذه التلميحات تحصل على الذهاب.هل قرأت على الانترنت pyparsing المقالات أو الدروس ؟ و يرجى ننظر من خلال الأمثلة على الانترنت.سوف تحتاج إلى الحصول على فهم جيد لكيفية Word, Literal, Combine, ، وما إلى ذلك.أداء الفرد تحليل المهام.

5) لديك سوء تنفيذ متكررة تعريفات المصطلح وبيان.بدلا من تعيين '' لهم الكتابة:

term = Forward()
statement = Forward()

ثم عندما تذهب إلى تعريف الواقع لهم العودية تعريفات, استخدام << مشغل (وتأكد من أن أرفق RHS في ()'s).

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

يمكنك العثور على مثال على العودية محلل هنا, و عرض الأساسية pyparsing الاستخدام هنا - انظر القسم بعنوان "تحليل القوائم" لمزيد من خطوة بخطوة حول كيفية العودية هو التعامل معها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top