簡體   English   中英

xtext 處理左遞歸語法

[英]xtext dealing with left recursion grammar

我正在使用 xtext 2.4 並希望同時支持 map 和 set,我的語法如下所示

<term> ::- <collection>
<collection> ::- <map> | <set>
<map> ::- '{' (<term> ':' <term> (',' <term> ':' <term> )*)? '}'
<set> ::- '{' (<term> (',' <term>)* )+ '}'

所以它可以簡化為

<term> ::- '{' (<term> ':' <term> (',' <term> ':' <term> )*)? '}' |
           '{' (<term> (',' <term>)* )+ '}'

antlr 抱怨這個語法開始左遞歸,我不知道為什么,因為它在右手邊有 '{' 。

即使我想分解相同的部分,我也不知道如何在 xtext 中做到這一點,因為一個 EObject 現在被分成兩個生產規則,並且解析的數據不能存儲在同一個對象中。

有什么幫助嗎?

================================================== ========================== 我寫的對應的xtext語法是

grammar org.xtext.problem.Term with org.eclipse.xtext.common.Terminals

generate term "http://www.xtext.org/problem/Term"

Term:
    term = Collection
;

Collection:
    MyMap | MySet
; 

MyMap:
    {MyMap} '{'( keys+= Term ':' values += Term ( ',' keys+=Term ':' values +=Term)*  )?'}'
;

MySet:
    {MySet} '{'( values += Term ( ',' values +=Term)*  )?'}'
;

錯誤消息(以error(211)開頭):

0    [main] INFO  lipse.emf.mwe.utils.StandaloneSetup  - Registering platform uri '/Users/jcwu/opensource/xtext-problemistic'
116  [main] INFO  lipse.emf.mwe.utils.StandaloneSetup  - Adding generated EPackage 'org.eclipse.xtext.xbase.XbasePackage'
454  [main] INFO  clipse.emf.mwe.utils.GenModelHelper  - Registered GenModel 'http://www.eclipse.org/Xtext/Xbase/XAnnotations' from 'platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel'
459  [main] INFO  clipse.emf.mwe.utils.GenModelHelper  - Registered GenModel 'http://www.eclipse.org/xtext/xbase/Xtype' from 'platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel'
479  [main] INFO  clipse.emf.mwe.utils.GenModelHelper  - Registered GenModel 'http://www.eclipse.org/xtext/xbase/Xbase' from 'platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel'
479  [main] INFO  clipse.emf.mwe.utils.GenModelHelper  - Registered GenModel 'http://www.eclipse.org/xtext/common/JavaVMTypes' from 'platform:/resource/org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel'
1660 [main] INFO  ipse.emf.mwe.utils.DirectoryCleaner  - Cleaning /Users/jcwu/opensource/xtext-problemistic/org.xtext.problem.term/../org.xtext.problem.term/src-gen
1665 [main] INFO  ipse.emf.mwe.utils.DirectoryCleaner  - Cleaning /Users/jcwu/opensource/xtext-problemistic/org.xtext.problem.term/../org.xtext.problem.term.ui/src-gen
1666 [main] INFO  ipse.emf.mwe.utils.DirectoryCleaner  - Cleaning /Users/jcwu/opensource/xtext-problemistic/org.xtext.problem.term/../org.xtext.problem.term.tests/src-gen
2033 [main] INFO  ipse.xtext.generator.LanguageConfig  - generating infrastructure for org.xtext.problem.Term with fragments : ImplicitRuntimeFragment, ImplicitUiFragment, GrammarAccessFragment, EcoreGeneratorFragment, SerializerFragment, ResourceFactoryFragment, XtextAntlrGeneratorFragment, ValidatorFragment, ImportNamespacesScopingFragment, QualifiedNamesFragment, BuilderIntegrationFragment, GeneratorFragment, FormatterFragment, LabelProviderFragment, OutlineTreeProviderFragment, QuickOutlineFragment, QuickfixProviderFragment, ContentAssistFragment, XtextAntlrUiGeneratorFragment, Junit4Fragment, RefactorElementNameFragment, TypesGeneratorFragment, XbaseGeneratorFragment, CodetemplatesGeneratorFragment, CompareFragment
4115 [main] INFO  clipse.emf.mwe.utils.GenModelHelper  - Registered GenModel 'http://www.xtext.org/problem/Term' from 'platform:/resource/org.xtext.problem.term/src-gen/org/xtext/problem/Term.genmodel'
error(211): ../org.xtext.problem.term/src-gen/org/xtext/problem/parser/antlr/internal/InternalTerm.g:119:1: [fatal] rule ruleCollection has non-LL(*) decision due to recursive rule invocations reachable from alts 1,2.  Resolve by left-factoring or using syntactic predicates or using backtrack=true option.
5918 [main] ERROR enerator.CompositeGeneratorFragment  - java.io.FileNotFoundException: ../org.xtext.problem.term/src-gen/org/xtext/problem/parser/antlr/internal/InternalTermLexer.java (No such file or directory)
org.eclipse.emf.common.util.WrappedException: java.io.FileNotFoundException: ../org.xtext.problem.term/src-gen/org/xtext/problem/parser/antlr/internal/InternalTermLexer.java (No such file or directory)
    at org.eclipse.xtext.util.Files.readFileIntoString(Files.java:129)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.suppressWarningsImpl(AbstractAntlrGeneratorFragment.java:132)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.suppressWarnings(AbstractAntlrGeneratorFragment.java:142)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.suppressWarnings(AbstractAntlrGeneratorFragment.java:138)
    at org.eclipse.xtext.generator.parser.antlr.XtextAntlrGeneratorFragment.generate(XtextAntlrGeneratorFragment.java:49)
    at org.eclipse.xtext.generator.CompositeGeneratorFragment.generate(CompositeGeneratorFragment.java:92)
    at org.eclipse.xtext.generator.LanguageConfig.generate(LanguageConfig.java:113)
    at org.eclipse.xtext.generator.Generator.generate(Generator.java:361)
    at org.eclipse.xtext.generator.Generator.invokeInternal(Generator.java:128)
    at org.eclipse.emf.mwe.core.lib.AbstractWorkflowComponent.invoke(AbstractWorkflowComponent.java:126)
    at org.eclipse.emf.mwe.core.lib.Mwe2Bridge.invoke(Mwe2Bridge.java:34)
    at org.eclipse.emf.mwe.core.lib.AbstractWorkflowComponent.invoke(AbstractWorkflowComponent.java:201)
    at org.eclipse.emf.mwe2.runtime.workflow.AbstractCompositeWorkflowComponent.invoke(AbstractCompositeWorkflowComponent.java:35)
    at org.eclipse.emf.mwe2.runtime.workflow.Workflow.run(Workflow.java:19)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:102)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:62)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:52)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher.run(Mwe2Launcher.java:74)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher.main(Mwe2Launcher.java:35)
Caused by: java.io.FileNotFoundException: ../org.xtext.problem.term/src-gen/org/xtext/problem/parser/antlr/internal/InternalTermLexer.java (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:97)
    at org.eclipse.xtext.util.Files.readFileIntoString(Files.java:126)
    ... 18 more
error(211): ../org.xtext.problem.term.ui/src-gen/org/xtext/problem/ui/contentassist/antlr/internal/InternalTerm.g:176:1: [fatal] rule rule__Collection__Alternatives has non-LL(*) decision due to recursive rule invocations reachable from alts 1,2.  Resolve by left-factoring or using syntactic predicates or using backtrack=true option.
6617 [main] ERROR enerator.CompositeGeneratorFragment  - java.io.FileNotFoundException: ../org.xtext.problem.term.ui/src-gen/org/xtext/problem/ui/contentassist/antlr/internal/InternalTermLexer.java (No such file or directory)
org.eclipse.emf.common.util.WrappedException: java.io.FileNotFoundException: ../org.xtext.problem.term.ui/src-gen/org/xtext/problem/ui/contentassist/antlr/internal/InternalTermLexer.java (No such file or directory)
    at org.eclipse.xtext.util.Files.readFileIntoString(Files.java:129)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.suppressWarningsImpl(AbstractAntlrGeneratorFragment.java:132)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.suppressWarnings(AbstractAntlrGeneratorFragment.java:142)
    at org.eclipse.xtext.generator.parser.antlr.AbstractAntlrGeneratorFragment.suppressWarnings(AbstractAntlrGeneratorFragment.java:138)
    at org.eclipse.xtext.generator.parser.antlr.XtextAntlrUiGeneratorFragment.generate(XtextAntlrUiGeneratorFragment.java:53)
    at org.eclipse.xtext.generator.CompositeGeneratorFragment.generate(CompositeGeneratorFragment.java:92)
    at org.eclipse.xtext.generator.LanguageConfig.generate(LanguageConfig.java:113)
    at org.eclipse.xtext.generator.Generator.generate(Generator.java:361)
    at org.eclipse.xtext.generator.Generator.invokeInternal(Generator.java:128)
    at org.eclipse.emf.mwe.core.lib.AbstractWorkflowComponent.invoke(AbstractWorkflowComponent.java:126)
    at org.eclipse.emf.mwe.core.lib.Mwe2Bridge.invoke(Mwe2Bridge.java:34)
    at org.eclipse.emf.mwe.core.lib.AbstractWorkflowComponent.invoke(AbstractWorkflowComponent.java:201)
    at org.eclipse.emf.mwe2.runtime.workflow.AbstractCompositeWorkflowComponent.invoke(AbstractCompositeWorkflowComponent.java:35)
    at org.eclipse.emf.mwe2.runtime.workflow.Workflow.run(Workflow.java:19)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:102)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:62)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Runner.run(Mwe2Runner.java:52)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher.run(Mwe2Launcher.java:74)
    at org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher.main(Mwe2Launcher.java:35)
Caused by: java.io.FileNotFoundException: ../org.xtext.problem.term.ui/src-gen/org/xtext/problem/ui/contentassist/antlr/internal/InternalTermLexer.java (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:97)
    at org.eclipse.xtext.util.Files.readFileIntoString(Files.java:126)
    ... 18 more
6650 [main] INFO  text.generator.junit.Junit4Fragment  - generating Junit4 Test support classes
6682 [main] INFO  text.generator.junit.Junit4Fragment  - generating Compare Framework infrastructure
7118 [main] INFO  .emf.mwe2.runtime.workflow.Workflow  - Done.

您的問題的有效 Xtext 語法是這樣的:

Model: term += Term*;

Term: c=Collection;

Collection: ( => Map | Set );

Map: '{' {Map} ( entries += MapEntry ( ',' entries += MapEntry )* )? '}';
MapEntry: key=Term ':' value=Term;

Set: '{' ( values += Term ( ',' values += Term )* )+ '}';

注意事項:

  • Collection規則中的=>語法謂詞。 這將 Xtext/ANTLR 引導到正確的方向。 文檔在這里

  • 即使內容為空, {Map} “簡單操作”( 此處為 Docu )也會創建一個Map

  • 還需要附加的MapEntry規則,否則您將無法保存鍵/值對。

  • 您的語法允許在Set同時使用{}{}{}{}, {}, {} 這可能是也可能不是您想要的。

所以在我看來,關於 LL 遞歸的 Xtext/ANTLR 錯誤消息在這種情況下並不是最合適的。 這不是關於 LL 遞歸,而是關於語法中的歧義,有時可以通過應用=>來解決。 有關更多詳細信息,請參閱鏈接的文檔。

僅供參考:語法可以解析這樣的簡單和嵌套的東西:

// Maps
{}
{ {} : {} }
{ {} : {}, {} : {}}

// Sets
{ {} }
{ {} {} {} {} }
{ {}, {}, {}, {} }

// nested / mixed
{ { { {}:{} } } : {}, {} : { {}:{} }}
{ { { {}:{} } } : {}, {} : { {}:{ {}{}{} } }}

暫無
暫無

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

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